【问题标题】:Validate XML with multiple namespace in Java在 Java 中使用多个命名空间验证 XML
【发布时间】:2016-09-21 19:47:10
【问题描述】:

我正在尝试验证使用多个名称空间的 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。 这些文件是:

ma​​in.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.

意思是,这在主命名空间中是意料之外的——这是可以理解的,因为元素本身在该命名空间中是未知的。我希望在主命名空间再次验证文档时忽略扩展命名空间的元素,反之亦然 - 这意味着我可以在主命名空间内的扩展命名空间之后嵌入文档。但这显然行不通。

我错过了什么?

【问题讨论】:

  • 你的 XSD 说你的“书”元素有一个“章节”元素的列表。你试图加入一个不同的元素。我不确定你的问题是什么。你想知道如何重写main.xsd 以允许播放音乐吗?
  • 我认为可以在不重写main.xsd 的情况下验证文档。这两个 XSD 并不真正相关。我假设我可以编写一个结合了两个 XSD 的 XSD,但这会很烦人,因为我的实际应用程序可能有几个可能存在或不存在的扩展 XSD - 并且列表可能会继续。 (将其视为一种插件的嵌入式子文档)。我的问题是是否有任何方法可以验证这一点,这样验证器就不会抱怨 extension.xsd 中的元素

标签: java xml validation xml-namespaces xsd-validation


【解决方案1】:

您的main.xsdbook 元素所允许的内容中是明确的。如果您想允许任何其他元素,您需要在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> 

【讨论】:

  • 谢谢。 ANY 元素是在保持主 XSD 不知道可能的扩展和仍然有效之间的一个很好的折衷,尽管未知(在main.xsd 内)元素出现在文档树中。这样我只需要在main.xsd中定义可能的扩展点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多