0

请在下面帮助我处理我的 Java/woodstox 代码。我还在示例中提供了一个 xsd 和两个 xml 文件。

主要问题

我打开了验证,预计会出现验证错误,因为

  • ID foo1 和 foo2 在 test2.xml 中定义了两次,
  • ID foo 在 test2.xml 中没有定义使用(除非考虑到来自 test1.xml 的 ID,因为我希望它使用 XInclude 发生),并且
  • ID foo3 在 test2.xml 中没有定义。但是,没有显示验证问题。

测试.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:attributeGroup name="ATTRIBUTES_TYPE_node">
        <xs:attribute name="id1" type="xs:ID" use="required"/>
        <xs:attribute name="id2" type="xs:ID" use="required"/>
        <xs:attribute name="idref" type="xs:IDREF" use="optional"/>
    </xs:attributeGroup>

    <xs:complexType name="TYPE_node">
        <xs:attributeGroup ref="ATTRIBUTES_TYPE_node"/>
    </xs:complexType>

    <xs:complexType name="TYPE_root">
        <xs:sequence>
            <xs:element name="node" type="TYPE_node" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="root" type="TYPE_root"/>

</xs:schema>

test1.xsd

<?xml version="1.1" encoding="utf-8"?>
<root
        xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
        vc:minVersion="1.1"
        vc:noNamespaceSchemaLocation="test.xsd">
    <node id1="foo" id2="bar" idref="foo"/>
</root>

test2.xsd

<?xml version="1.1" encoding="utf-8"?>
<root
        xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
        vc:minVersion="1.1"
        xmlns:xi="http://www.w3.org/2001/XInclude"
        vc:noNamespaceSchemaLocation="test.xsd">
    <xi:include href="test1.xml">
        <xi:fallback/>
    </xi:include>

    <node id1="foo1" id2="foo2" idref="foo"/>
    <node id1="foo1" id2="foo2" idref="foo3"/>
</root>

Java 代码

XMLInputFactory xmlInputFactory = XMLInputFactory2.newInstance();
xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
xmlInputFactory.setProperty(XMLInputFactory.IS_VALIDATING, true);
xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileReader("src/main/resources/test2.xml"));

try {
    xmlStreamReader.nextTag();
    xmlStreamReader.require(XMLStreamConstants.START_ELEMENT, null, "root");
    xmlStreamReader.nextTag();

    while (true) {
        if (xmlStreamReader.getEventType() == XMLStreamConstants.START_ELEMENT)
            for (int i = 0; i < xmlStreamReader.getAttributeCount(); i++) {
                System.out.println("getAttributePrefix=" + xmlStreamReader.getAttributePrefix(i));
                System.out.println("getAttributeLocalName=" + xmlStreamReader.getAttributeLocalName(i));
                System.out.println("getAttributeName=" + xmlStreamReader.getAttributeName(i));
                System.out.println("getAttributeNamespace=" + xmlStreamReader.getAttributeNamespace(i));
                System.out.println("getAttributeType=" + xmlStreamReader.getAttributeType(i));
                System.out.println("getAttributeValue=" + xmlStreamReader.getAttributeValue(i));
            }
        xmlStreamReader.next();
    }
} finally {
    xmlStreamReader.close();
}

我尝试过的

我应该更好地使用 SAXParserFactory saxParserFactory = WstxSAXParserFactory.newInstance(); 而不是 XMLInputFactory xmlInputFactory = XMLInputFactory2.newInstance(); 作为第一步吗?有什么区别?

但是,在设置“不支持指定的模式语言”时saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage","http://www.w3.org/2007/XMLSchema-versioning"); ,我遇到了问题 。SAXNotSupportedException结果。

至少我可以在那里 xmlReader.setErrorHandler(new SimpleErrorHandler()); 安装一个错误处理程序,我在上面的代码中没有这样做。

插件问题1

什么对我更好:createXMLStreamReadercreateXMLEventReader

插件问题2

我需要调整我的 XSD/XML 文件吗?尤其是标题?

插件问题3

我需要在解析/验证之前解决 Xincludes 吗?如果是这样,怎么做?

进一步的背景

  • 显然,代码处于早期阶段,我不太关心它是如何结束的。
  • 我使用 XML1.1 因为我需要具有多个 ID 属性的 xml-tags。
  • 我使用 XInclude 是因为我想以模块化方式定义我的 xml 文件以避免 xml 代码重复。
  • Intellij 不验证我的文件,所以我特此尝试更深入地挖掘,但我认为这些问题到目前为止是不相关的,因为在这里我没有遇到验证问题,而我在另一个线程中遇到了一个问题
  • 我将(几乎相同的问题)发布到 Woodstox 邮件列表,但几乎没有任何活动。线
4

1 回答 1

0

几点:

  1. 当您说 XML 1.1 时,我认为您的意思是 XSD 1.1。

  2. 您的 Woodstox 代码不会尝试启用模式验证。

  3. 为普通 XML 实例文件而不是模式文档的文件使用 .xsd 文件扩展名会令人困惑(但实际上并非不正确)。

  4. 我不知道是否有任何方法可以使用 Woodstox 启用架构验证(尤其是 XSD 1.1 验证)。除了使用 Saxon 验证器,它允许模式验证器的输入是 StAXSource。

  5. Java 世界中有两种 XSD 1.1 处理器可用:Xerces 和 Saxon。如果您要使用 Xerces 模式验证器,我认为您可能需要将它与 Xerces XML 解析器一起使用(可能可以将它们解耦,但我不知道您为什么要这样做)。如果您选择 Saxon XSD 处理器,那么它将与任何 SAX 或 StAX 解析器一起使用,但我认为使用 StAX(即 Woodstox)没有任何好处,因为 XSD 处理器位于推送管道上,这使得 SAX 更好合身。

  6. 关于 XInclude 处理,我想您可能想在 XSD 验证之前进行 XInclude 处理?当您使用 Xerces 作为 XML 解析器并使用 Saxon 作为模式验证器时,这很容易。其他产品组合也有可能,我不确定。

于 2021-07-23T13:16:48.147 回答