Контекст: я пытаюсь найти способ проверки XSD и XML на XSD, который можно автоматизировать для интеграции в процесс сборки программного обеспечения. Входными данными являются файлы, и для вывода будет достаточно кода выхода или вывода консоли с надежным регулярным выражением. Я работаю в среде Windows.
В качестве входных данных XML и XSD я взял пример из Википедии (статья «Схема XML (W3C)»).
В качестве инструментов я выбрал XMLLint и Xerces.
Проблема в том, что XMLLint и Xerces дают разные результаты.
Это приводит меня к моим вопросам: какие еще варианты оценки инструментов у меня есть? Как мне решить, какой инструмент выбрать?
Пример данных XML из Википедии, SimpleAddress.xml:
<?xml version="1.0" encoding="utf-8"?>
<Address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="SimpleAddress.xsd">
<Recipient>Mr. Walter C. Brown</Recipient>
<House>49</House>
<Street>Featherstone Street</Street>
<Town>LONDON</Town>
<PostCode>EC1Y 8SY</PostCode>
<Country>UK</Country>
</Address>
Пример схемы XSD из Википедии, SimpleAddress.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="Recipient" type="xs:string" />
<xs:element name="House" type="xs:string" />
<xs:element name="Street" type="xs:string" />
<xs:element name="Town" type="xs:string" />
<xs:element name="County" type="xs:string" minOccurs="0" />
<xs:element name="PostCode" type="xs:string" />
<xs:element name="Country" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="IN" />
<xs:enumeration value="DE" />
<xs:enumeration value="ES" />
<xs:enumeration value="UK" />
<xs:enumeration value="US" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Сначала мои тесты с XMLLint:
$ xmllint.exe --noout --schema SimpleAddress.xsd SimpleAddress.xml
SimpleAddress.xml validates
$ xmllint.exe --noout --schema http://www.w3.org/2001/XMLSchema.xsd SimpleAddress.xsd
SimpleAddress.xsd validates
XMLLint также дает значимые результаты ошибок, когда я намеренно помещаю дополнительный атрибут или тег в файл для проверки.
С помощью XMLLint я также попытался проверить определение схемы XML W3C на его соответствие самому себе:
$ xmllint.exe --noout --schema http://www.w3.org/2001/XMLSchema.xsd http://www.w3.org/2001/XMLSchema.xsd
http://www.w3.org/2001/XMLSchema.xsd validates
Во-вторых, мои тесты с Xerces, которые дают много предупреждений и ошибок:
$ StdInParse.exe -n -s -f -v=always < SimpleAddress.xml
stdin: 1 ms (7 elems, 2 attrs, 19 spaces, 56 chars)
$ StdInParse.exe -n -s -f -v=always < SimpleAddress.xsd
Error at (file stdin, line 2, char 87): no declaration found for element 'xs:schema'
Error at (file stdin, line 2, char 87): attribute 'elementFormDefault' is not declared for element 'xs:schema'
Error at (file stdin, line 2, char 87): attribute '{http://www.w3.org/2000/xmlns/}xs' is not declared for element 'xs:schema'
Error at (file stdin, line 3, char 30): no declaration found for element 'xs:element'
(…)
Для следующих тестов я добавил атрибуты «xmlns: xsi» и «xsi: schemaLocation» к открывающему тегу SimpleAddress.xsd:
<xs:schema
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema.xsd"
>
XMLLint дает тот же результат:
$ xmllint.exe --noout --schema http://www.w3.org/2001/XMLSchema.xsd SimpleAddress.xsd
SimpleAddress.xsd validates
Xerces выдает еще больше предупреждений и ошибок, теперь также касающихся документов W3C:
$ StdInParse.exe -n -s -f -v=always < SimpleAddress.xsd
Warning at (file http://www.w3.org/2001/datatypes.dtd, line 99, char 7): attribute 'id' has already been declared for element 'xs:simpleType'
Warning at (file http://www.w3.org/2001/datatypes.dtd, line 122, char 7): attribute 'id' has already been declared for element 'xs:list'
Warning at (file http://www.w3.org/2001/datatypes.dtd, line 130, char 7): attribute 'id' has already been declared for element 'xs:union'
Warning at (file http://www.w3.org/2001/datatypes.dtd, line 140, char 20): attribute 'id' has already been declared for element 'xs:maxExclusive'
(…)
Error at (file stdin, line 15, char 68): unable to find validator for simple type of attribute 'maxOccurs'
Error at (file stdin, line 16, char 56): unable to find validator for simple type of attribute 'maxOccurs'
Error at (file stdin, line 17, char 50): unable to find validator for simple type of attribute 'maxOccurs'
В заключение XMLLint, похоже, делает то, что мне нужно, однако у него есть один серьезный недостаток. Это требует от меня указать файл XSD для проверки в качестве отдельного аргумента, поскольку он, похоже, не может прочитать соответствующий атрибут xmlns из входных файлов XML.
С другой стороны, есть Xerces. Похоже, что он широко используется и утверждает, что соответствует тем же стандартам, что и в такого рода документах, но дает множество ошибок и предупреждений даже в отношении документов W3C. Итак, я спрашиваю себя, правильно ли я его использую? Я бы хотел, чтобы он работал, поскольку мне не нужно было бы искать обходной путь для необходимого дополнительного аргумента XMLLint.