Автор |
Сообщение |
Любчик
Новичок
Зарегистрирован: 07.06.2009
Сообщения: 4
Откуда: *.lviv.ua
|
[13817]
Вс Июн 07, 2009 23:08
внешнее связывание с помощью xsd:IDREF и XSLT
здравствуйте!
очень интересует ответ на следующий вопрос, на который не в состоянии ответить даже гугл (я уже не знаю как гуглить по-другому, дней 3 уже роюсь)
после упорнейшего поиска нашёл что-то только два более-менее применимых ответа, но они меня не совсем удовлетворили
я уже даже рассматриваю регистрацию на вашем форуме как последнюю надежду, честно )))
давайте взглянем на следующий пример
допустим, у нас есть некое описание дискографии (пусть это будет последний диск The Prodigy "Invaders Must Die") в xml:
Код: [ tracks.xml ]
<?xml version="1.0" encoding="utf-8" ?>
<tracks xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="tracks.xsd">
<track id="invaders-must-die" title="Invaders Must Die" />
<track id="omen" title="Omen" />
<track id="thunder" title="Thunder" />
<track id="colours" title="Colours" />
<track id="take-me-to-the-hospital" title="Take Me to the Hospital" />
<track id="warrior-s-dance" title="Warrior's Dance" />
<track id="run-with-the-wolves" title="Run with the Wolves" />
<track id="omen-reprise" title="Omen Reprise" />
<track id="world-s-on-fire" title="World's on Fire" />
<track id="piranha" title="Piranha" />
<track id="stand-up" title="Stand Up" />
</tracks>
[ discography.xml ]
<?xml version="1.0" encoding="utf-8" ?>
<discography xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="discography.xsd">
<release year="2009" title="Invaders Must Die">
<track ref="invaders-must-die" />
<track ref="omen" />
<track ref="thunder" />
<track ref="colours" />
<track ref="take-me-to-the-hospital" />
<track ref="warrior-s-dance" />
<track ref="run-with-the-wolves" />
<track ref="omen-reprise" />
<track ref="world-s-on-fire" />
<track ref="piranha" />
<track ref="stand-up" />
</release>
</discography>
[ tracks.xsd ]
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="tracks">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="track" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:ID" use="required" />
<xsd:attribute name="title" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
[ discography.xsd ]
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="discography">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="release" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="track" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="ref" type="xsd:IDREF" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="year" type="xsd:int" use="optional" />
<xsd:attribute name="title" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
грубо говоря, это два XML-файла, которые представляют из себя две таблицы с отношением "один ко многим"
и вот беда — валидатор вполне оправданно считает, что в discography.xml этих id нет, но он, к сожалению,
не знает, что я указал идентификаторы узлов, находящиеся в другом документе
собственно, каким образом нужно изменить discography.xsd, чтобы в атрибуте ref можно было ссылаться на узлы с атрибутом id из tracks.xml?
видел решение с XML-сущностями, описанными в DTD, но оно меня далеко не совсем устраивает
а также, как правильно работать с такими отношениями в XSLT/XPath?
неужели только через функцию document()? или существует более (возможно, синтаксически) элегантные манипулирование
и преобразование элементов, содержащих @id и @ref из разных документов?
спасибо!
|
Vasilisk
Наставник
Зарегистрирован: 17.05.2006
Сообщения: 370
Откуда: Украина, Харьков
|
[13823]
Пн Июн 08, 2009 22:07
Ищу решение этой задачи уже года два и, имхо, решения в стандартных парсерах она не имеет.
P.S. Вместо xsd:ID и xsd:IDREF рекомендую использовать <xsd:key> и <xsd:keyref>
P.P.S. А, что неэлегантного в функции document()?
_________________ С уважением Vasilisk
Уважайте читающих, используйте тэги [code ][/code]
|
Гость
|
[13824]
Вт Июн 09, 2009 13:40
Цитата: Ищу решение этой задачи уже года два и, имхо, решения в стандартных парсерах она не имеет.
офигеть...
я верил (ага, именно верил) в то, что такая тривиальная задача должна решиться очень просто
подозрения начали возникать тогда, когда гугление начало напоминать стрельбу из танка по воробьям
да, жаль, причём я в недоумении, почему такую функциональность не можно было бы стандартизировать с самого начала
Цитата: P.S. Вместо xsd:ID и xsd:IDREF рекомендую использовать <xsd:key> и <xsd:keyref>
м-м-м, ок, спасибо
извините за глупый вопрос вдогонку, но оно как-то позволяет организировать связывание между разными документами?
Цитата: P.P.S. А, что неэлегантного в функции document()?
я просто подумал, что если встречается @id из другого документа, тогда шаблоны могли бы резолвиться как-то по-другому
а так, насколько я понимаю, document() жёстко привязывается к имени документа (что, в принципе, в этом случае не совсем-то и гут)
т.е., я думал, что, может, это как-то решается испольозованием пространств имён (опять же - как?) или синтаксическими конструкциями
совсем запутался
|
Vasilisk
Наставник
Зарегистрирован: 17.05.2006
Сообщения: 370
Откуда: Украина, Харьков
|
[13825]
Вт Июн 09, 2009 21:48
Anonymous писал(а): Цитата: P.S. Вместо xsd:ID и xsd:IDREF рекомендую использовать <xsd:key> и <xsd:keyref>
м-м-м, ок, спасибо
извините за глупый вопрос вдогонку, но оно как-то позволяет организировать связывание между разными документами? Никак. Но в пределах одного документа возможностей на порядок больше.
Anonymous писал(а): насколько я понимаю, document() жёстко привязывается к имени документа (что, в принципе, в этом случае не совсем-то и гут) Нет. В качестве аргумента нужно указать строку с именем внешнего документа. А где Вы эту строку возьмете - жестко забьете или прочитаете из соседнего узла, XSLT-процессору слабо интересно.
А основная проблема в валидации двух (и более) XML документов состоит в том, что парсер не знает где брать оставшиеся части.
Кстати, посмотрите XInclude. Может подойдет?
_________________ С уважением Vasilisk
Уважайте читающих, используйте тэги [code ][/code]
|
Любчик
Новичок
Зарегистрирован: 07.06.2009
Сообщения: 4
Откуда: *.lviv.ua
|
[13837]
Пн Июн 15, 2009 00:49
Цитата: Нет. В качестве аргумента нужно указать строку с именем внешнего документа. А где Вы эту строку возьмете - жестко забьете или прочитаете из соседнего узла, XSLT-процессору слабо интересно.
хм... я почему-то не подумал о создании как бы core-документа, в котором были бы как-то прописаны все ссылаемые документы (по id, например, но пусть уже всё-равно было бы на валидацию - по ходу, если целостность к тем узлам будет нарушена, тогда просто прописаный документ не подгрузится [это пока то, каким я это вижу])
я почему это спрашивал - мне хотелось как бы алиас создать для документа, но это более-менее (вроде ))) ) решается присвоением значения XSLT-переменной (но id() не работает)
Цитата: А основная проблема в валидации двух (и более) XML документов состоит в том, что парсер не знает где брать оставшиеся части.
вот именно...
Цитата: Кстати, посмотрите XInclude. Может подойдет?
смотрел немножко в ту сторону, но насколько я понял, браузеры не поддерживают эту технологию (и, насколько я понимаю, возможен конфликт id в результирующем документе)
буду очень признателен за поправки и советы
|
Vasilisk
Наставник
Зарегистрирован: 17.05.2006
Сообщения: 370
Откуда: Украина, Харьков
|
[13839]
Пн Июн 15, 2009 21:30
Любчик писал(а): Цитата: Кстати, посмотрите XInclude. Может подойдет?
смотрел немножко в ту сторону, но насколько я понял, браузеры не поддерживают эту технологию При чем тут браузеры?
Любчик писал(а): (и, насколько я понимаю, возможен конфликт id в результирующем документе)
Цитата: Вместо xsd:ID и xsd:IDREF рекомендую использовать <xsd:key> и <xsd:keyref>
_________________ С уважением Vasilisk
Уважайте читающих, используйте тэги [code ][/code]
|
Любчик
Новичок
Зарегистрирован: 07.06.2009
Сообщения: 4
Откуда: *.lviv.ua
|
[13841]
Пн Июн 15, 2009 21:56
Цитата: При чем тут браузеры?
потому что нужно именно под браузерами гонять те документы без какой-либо предварительной обработки
вот с XSLT справляются же
Цитата: << (и, насколько я понимаю, возможен конфликт id в результирующем документе)
>> Вместо xsd:ID и xsd:IDREF рекомендую использовать <xsd:key> и <xsd:keyref>
ааа, понятно, спасибо =)
|
Vasilisk
Наставник
Зарегистрирован: 17.05.2006
Сообщения: 370
Откуда: Украина, Харьков
|
[13842]
Пн Июн 15, 2009 22:43
Любчик писал(а): потому что нужно именно под браузерами гонять те документы без какой-либо предварительной обработки
XML без предварительной обработки это plain/text
Любчик писал(а): вот с XSLT справляются же Это уже обработка. А в таком случае Вам доступны как стандартная функция document() так и собственные расширения
_________________ С уважением Vasilisk
Уважайте читающих, используйте тэги [code ][/code]
|
Любчик
Новичок
Зарегистрирован: 07.06.2009
Сообщения: 4
Откуда: *.lviv.ua
|
[13846]
Ср Июн 17, 2009 03:56
Цитата: XML без предварительной обработки это plain/text
ну, это с какой стороны посмотреть ))) браузер знает, что это text/xml ))
я имел в виду, что web-сервер вообще никак не обрабатывает те документы, а просто по GET-запросу их отсылает клиенту
и браузер уже что-то там шаманит с XSLT и показывает конечному пользователю )))
собственно, мне нечего больше добавить в вопросе, а вся вышеизложенная информация для меня оказалась очень ценной
Vasilisk, спасибо огромное!
|