xmlhack.ru XML-форумы
Обсуждение XML и связанных с ним технологий

внешнее связывание с помощью xsd:IDREF и XSLT


Автор Сообщение
Любчик
Новичок

Зарегистрирован: 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() жёстко привязывается к имени документа (что, в принципе, в этом случае не совсем-то и гут)
т.е., я думал, что, может, это как-то решается испольозованием пространств имён (опять же - как?) или синтаксическими конструкциями
совсем запутался Sad
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, спасибо огромное! Smile