我正在使用xmllint进行一些验证,我有一个XML实例文档需要针对两个模式进行验证:一个用于外部"信封"(包括任何元素),另一个用于特定有效负载.假设A.xsd是信封模式,B.xsd是有效负载模式(有不同的可能有效负载),ab.xml是有效的XML实例文档(我在帖子的末尾提供了一个示例).
我在同一目录中有本地可用的所有三个文件,并使用xmllint执行验证,提供外部(信封)模式的位置作为模式参数:
xmllint -schema A.xsd ab.xml
Run Code Online (Sandbox Code Playgroud)
...但是,虽然我在实例文档中提供了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
Run Code Online (Sandbox Code Playgroud)
显然xmllint没有读取xsi:schemaLocation元素.我知道xmllint可以配置目录,但我没有让xmllint找到两个模式.在验证实例文档时,如何让xmllint考虑两个模式,或者我可以使用另一个命令行实用程序或图形工具?
<?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>
Run Code Online (Sandbox Code Playgroud)
<?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>
Run Code Online (Sandbox Code Playgroud)
<?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>
Run Code Online (Sandbox Code Playgroud)
Mar*_*tus 12
我退出xmllint并使用Xerces代替.
我下载了Xerces tarball,在将其爆炸到某个本地文件夹后,我根据此建议创建了以下验证脚本(来自Web存档 - 原始链接现已死亡):
#!/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 $*
Run Code Online (Sandbox Code Playgroud)
该ab.xml然后文件进行验证,对两种模式中,使用下面的命令:
validate -v -n -np -s -f ab.xml
Run Code Online (Sandbox Code Playgroud)
Xerces正在从ab.xml中的xsi:schemaLocation元素读取模式位置,因此不需要在命令行调用中提供它们.
您可以创建包装器模式并导入两个名称空间.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>
Run Code Online (Sandbox Code Playgroud)
然后:
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
Run Code Online (Sandbox Code Playgroud)
如果您在打开标签后有一个import元素,A.xsdschema
<xsd:import namespace="http://www.example.org/B" schemaLocation="B.xsd"/>
Run Code Online (Sandbox Code Playgroud)
然后你可以传递A.xsd给xmllint它,它将适用于:
xmllint -schema A.xsd ab.xml
Run Code Online (Sandbox Code Playgroud)