使用Java中的多个名称空间验证XML
问题描述:
我想验证使用多个名称空间的XML文档。我想在主命名空间的文档中嵌入辅助命名空间的标签。主/主名称空间不“知道”扩展名/辅助名称空间。使用Java中的多个名称空间验证XML
的test.xml
<?xml version="1.0" encoding="UTF-8"?>
<book
xmlns ="MyMain_FPI"
xmlns:ns2="MyExtension_FPI"
>
<ns2:playmusic/>
<chapter/>
<chapter/>
</book>
进行验证的Java代码如下:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new Source[] {
new StreamSource(new FileInputStream("main.xsd")),
new StreamSource(new FileInputStream("extension.xsd")),
});
factory.setSchema(schema);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("test.xml"));
正如你所看到的,我直接的XSD文件添加到的DocumentBuilderFactory。 这些文件是:
main.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="MyMain_FPI"
targetNamespace="MyMain_FPI"
elementFormDefault="qualified">
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="chapter"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="chapter">
<xs:complexType/>
</xs:element>
</xs:schema>
extension.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="MyExtension_FPI"
targetNamespace="MyExtension_FPI"
elementFormDefault="qualified">
<xs:element name="playmusic">
</xs:element>
</xs:schema>
上面执行代码时,我得到的错误是
[Error] test.xml:6:18: cvc-complex-type.2.4.a: Ungültiger Content wurde beginnend mit Element 'ns2:playmusic' gefunden. '{"MyMain_FPI":chapter}' wird erwartet.
含义,这在主命名空间中是意外的 - 这是可以理解的,因为该元素本身在该命名空间中是未知的。我期望扩展命名空间的元素在将文档再次验证为主命名空间时被忽略,反之亦然 - 这意味着我可以在主命名空间内的扩展命名空间后面嵌入文档。但这显然不起作用。
我错过了什么?
答
您的main.xsd
明确表示book
元素允许的内容。如果你想允许任何额外的元素,你需要在main.xsd
中声明。之后你可以添加任何你想要的扩展XSD。见https://www.w3.org/TR/xmlschema-0/#any。
新main.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="MyMain_FPI"
targetNamespace="MyMain_FPI"
elementFormDefault="qualified">
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" />
<xs:element maxOccurs="unbounded" ref="chapter"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="chapter">
<xs:complexType/>
</xs:element>
</xs:schema>
+0
的元素谢谢。尽管未知(在main.xsd中)元素出现在文档树中,但ANY元素是保持主XSD不知道可能的扩展并仍然有效的良好折衷。这样我只需要在'main.xsd'中定义可能的扩展点。 – taranion
你的XSD说,你的“书”元素有“章”元素的列表。您试图放入不同的元素。我不确定你的问题是什么。你想知道如何重写'main.xsd'来允许playmusic? –
我认为可以在不重写'main.xsd'的情况下验证文档。两个XSD都没有真正相关。 我假设我可以编写一个结合了两个XSD的XSD,但这很烦人,因为我的真实应用程序可能有几个可能存在或不存在的扩展XSD - 并且该列表可能会继续。 (把它看作是一种插件的嵌入式子文档)。 我的问题是,如果有任何方法来验证这一点,以便验证器不会抱怨extension.xsd – taranion