Простое использование xinclude в xml документах

Я нашел несколько вопросов, касающихся xinclude, но ни один из них не дал конкретного ответа на мой основной вопрос о том, как включить внешние документы.

Вот пара документов в формате xml, которые я хотел бы проверить друг друга:

<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test test-schema.xsd"
    xmlns:t="http://test">

    <t:first-name>Wilma</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/TR/xinclude" href="fred.xml"/>
    </t:spouse>

    </t:person>

<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://test test-schema.xsd"
 xmlns:t="http://test">
    <t:first-name>Fred</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/TR/xinclude" href="wilma.xml"/>
    </t:spouse>
</t:person>

и схема:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://test"
    targetNamespace="http://test" elementFormDefault="qualified"> 

<xs:element name="person" type="personType"/>


<xs:complexType name="personType">
    <xs:sequence>
        <xs:element name="first-name" type="xs:string"/>
        <xs:element name="last-name" type="xs:string"/>
        <xs:element name="spouse" type="personType"/>
    </xs:sequence>
</xs:complexType>

</xs:schema>

элемент xi: include считается недействительным. Я искал вокруг, и не могу найти простой пример, как это. XI: включает просто замену для элемента, который должен быть там, правильно?

спасибо, бп

2 ответа

Решение

Тот, кто хочет выполнить как проверку, так и обработку XInclude, может пожелать сначала выполнить XInclude, затем выполнить проверку или сначала выполнить проверку, затем выполнить XInclude или сначала выполнить проверку, затем выполнить обработку XInclude, а затем выполнить проверку снова. В текущем состоянии технологии чтения мыслей программное обеспечение не может определить, какой из них желателен, без помощи человека. Вы знаете, в каком порядке вы хотите, чтобы вещи происходили, но сказали ли вы свое программное обеспечение? Из вашего описания звучит так, как будто ваш процессор по умолчанию сначала проверяет, затем делает XInclude; если вам нужна последовательность обработки не по умолчанию, вам придется сообщить об этом вашему процессору. То, как вы это делаете, зависит от процессора; прочитайте документацию

У вас неправильное пространство имен для Xinclude.

Бег xmllint --xinclude ни в одном из ваших XML-файлов не происходит никаких изменений, поскольку он не распознается как оператор xinclude.

Измените пространство имен на: xmlns:xi="http://www.w3.org/2001/XInclude"

И это внесет некоторые изменения в вывод, но вы также получите ошибку во взаимной рекурсии:

$xmllint --xinclude wilma.xml 
fred.xml:8: element include: XInclude error : detected a recursion in wilma.xml
<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://test" xsi:schemaLocation="http://test test-schema.xsd">
    <t:first-name>Wilma</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://test" xsi:schemaLocation="http://test test-schema.xsd">
    <t:first-name>Fred</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="wilma.xml"/>
    </t:spouse>
</t:person> 
    </t:spouse>
</t:person>

XInclude должен рекурсивно обрабатывать xinclude, однако в соответствии с http://www.w3.org/TR/xinclude/:

При рекурсивной обработке элемента xi:include обработать другой элемент xi:include со значением include и значением атрибута xpointer, которые уже были обработаны в цепочке включения, является фатальной ошибкой.

Кроме того, когда вы пытаетесь проверить его по схеме, помимо ошибки рекурсии, вы получаете:

fred.xml:4: element person: Schemas validity error : Element '{http://test}person': This element is not expected. Expected is ( {http://test}first-name ).
wilma.xml fails to validate

Я полагаю, что это потому, что ваша схема говорит, что супруг IsA personType, но в вашем xml супруг содержится элемент personType: person.

Плюс то, что см-сперберг-маккуин сказал выше.

Если вы хотите, чтобы он был проверен перед выполнением расширения xinclude, то вам нужно включить элемент xi:include и его атрибуты в схему.

Если вы хотите, чтобы проверка выполнялась после выполнения расширения xinclude, процессор xinclude (если вы не указали это каким-либо образом) обычно добавляет атрибут xml:base к включаемому элементу, поэтому вам нужно будет добавить xml:base в качестве допустимого атрибут в схеме. (Сначала я думал, что, поскольку пространство имен xml зарезервировано, эти атрибуты xml: не нужно включать в схему, но это не так.)

Другие вопросы по тегам