【问题标题】:Woodstox/XML1.1/XSD Parsing+Validation and XIncludeWoodstox/XML1.1/XSD 解析+验证和 XInclude
【发布时间】:2021-09-30 10:55:37
【问题描述】:

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

主要问题

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

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

test.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

在解析/验证之前是否需要解析 Xinclude?如果有,怎么做?

进一步的上下文

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

【问题讨论】:

    标签: java xml xsd woodstox


    【解决方案1】:

    几点:

    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 作为模式验证器时,这很容易。其他产品组合也有可能,我不确定。

    【讨论】:

      猜你喜欢
      • 2013-08-23
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 2015-06-28
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 2019-11-30
      相关资源
      最近更新 更多