Xmllint: проверить XML файл на две схемы XSD (конверт/полезная нагрузка)

Я использую xmllint, чтобы выполнить некоторые проверки, и у меня есть документ экземпляра XML, который должен проверяться на двух схемах: один для внешний "конверт" (который включает элемент любой) и один для конкретной полезной нагрузки. Скажем A.xsd - схема огибающей, B.xsd схема полезной нагрузки (есть разные возможные полезные нагрузки) и ab.xml действительный XML экземпляр документа (я предоставляю пример в конце сообщения).

У меня есть все три файла, локально доступные в одном каталоге, и я использую xmllint для выполнения проверки, предоставляя в качестве аргумента схемы расположение внешней (конвертной) схемы:

xmllint -schema A.xsd ab.xml

... все же, хотя я предоставляю расположение как A.xsd, так и B.xsd в документе экземпляра (используя элемент xsi: schemaLocation) xmllint не работает найти его и жалуется:

ab.xml:8: element person: Schemas validity error : Element '{http://www.example.org/B}person': No matching global element declaration available, but demanded by the strict wildcard.
ab.xml fails to validate

Таким образом, очевидно, что xmllint не читает элемент xsi: schemaLocation. Я понимаю, что xmllint можно настроить с помощью каталогов, но мне не удалось получить xmllint, чтобы найти обе схемы. Как мне получить xmllint, чтобы учесть обе схемы при проверке документа экземпляра или есть ли еще одна утилита командной строки или графический инструмент, который я мог бы использовать вместо этого?

SSCCE

A.xsd - схема конверта

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

       <element name="someType" type="a:SomeType"></element>

        <complexType name="SomeType">
            <sequence>
                <any namespace="##other" processContents="strict"/>
            </sequence>
        </complexType>
</schema>

B.xsd - схема полезной нагрузки

<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
    xmlns          ="http://www.w3.org/2001/XMLSchema"
    xmlns:b        ="http://www.example.org/B"
    targetNamespace="http://www.example.org/B"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <element name="person" type="b:PersonType"></element>
    <complexType name="PersonType">
        <sequence>
                <element name="firstName" type="string"/>
                <element name="lastName"  type="string"/>
        </sequence>
    </complexType>
  </schema>

ab.xml - документ экземпляра

<?xml version="1.0" encoding="UTF-8"?>
<a:someType xmlns:a="http://www.example.org/A"
        xmlns:b="http://www.example.org/B"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.example.org/A A.xsd
                            http://www.example.org/B B.xsd">

            <b:person>
                <b:firstName>Mary</b:firstName>
                <b:lastName>Bones</b:lastName>
            </b:person>

</a:someType>

Ответы

Ответ 1

Я выхожу из xmllint и вместо этого использую Xerces.

Я загрузил tara Xerces и после взлома его в какую-то локальную папку я создал следующую проверку script (на основе это предложение):

#!/bin/bash
XERCES_HOME=~/software-downloads/xerces-2_11_0/
echo $XERCES_HOME
java -classpath $XERCES_HOME/xercesImpl.jar:$XERCES_HOME/xml-apis.jar:$XERCES_HOME/xercesSamples.jar sax.Counter $*

Затем файл ab.xml проверяется по обеим схемам с помощью следующей команды:

 validate -v -n -np -s -f ab.xml

Xerces считывает расположения схемы из элемента xsi: schemaLocation в ab.xml, поэтому их не нужно указывать в вызове командной строки.

Ответ 2

Если у вас есть import элемент в A.xsd, сразу после открытия тега schema,

<xsd:import namespace="http://www.example.org/B" schemaLocation="B.xsd"/>

то вы можете передать A.xsd в xmllint, и он будет работать с:

xmllint -schema A.xsd ab.xml

Ответ 3

Вы можете создать схему-оболочку и импортировать оба пространства имен. AB.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema">
    <import namespace="http://www.example.org/A" schemaLocation="A.xsd"/>
    <import namespace="http://www.example.org/B" schemaLocation="B.xsd"/>
</schema>

Тогда:

xmllint --schema AB.xsd ab.xml
<?xml version="1.0" encoding="UTF-8"?>
<a:someType xmlns:a="http://www.example.org/A" xmlns:b="http://www.example.org/B" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/A A.xsd                             http://www.example.org/B B.xsd">

            <b:person>
                <b:firstName>Mary</b:firstName>
                <b:lastName>Bones</b:lastName>
            </b:person>

</a:someType>
ab.xml validates