【问题标题】:Parsing XML with structured element names使用结构化元素名称解析 XML
【发布时间】:2016-09-10 14:17:03
【问题描述】:

我有一些第三方 XML 以下列形式解析。测试的数量是无限的,但总是一个整数。

<tests>
    <test_1>
        <foo bar="baz" />
    </test_1>

    <test_2>
        <foo bar="baz" />
    </test_2>

    <test_3>
        <foo bar="baz" />
    </test_3>
</tests>

我目前正在使用 XPath 解析它,但它很麻烦。有什么方法可以在 XSD 模式中表达这种 XML 风格并从中生成 JAXB 类。

据我所知,这是不可能的,唯一可能的是来自 how can I define an xsd file that allows unknown (wildcard) elements? &lt;xs:any processContents="lax"/&gt; 技术,但是这允许任何内容,而不是特别是&lt;test_&lt;integer&gt;。我只是想确认我没有遗漏一些 XSD/JAXB 技巧?

请注意,我更希望 XML 具有这样的结构。我可能会尝试说服第三方进行更改。

<tests>
    <test id="1">
        <foo bar="baz" />
    </test>

    <test id="2">
        <foo bar="baz" />
    </test>

    <test id="3">
        <foo bar="baz" />
    </test>
</tests>

【问题讨论】:

  • XSD 以一组固定的元素/类型为中心。 JAXB 只是从它们创建类。如何确定具有命名方案“test_xxx”的不同元素的数量? --- 但是,我看到了另一种选择:首先使用 XSLT 将带有这些元素的传入 XML 更改为适合您的需要并使用 &lt;test id="xxx"&gt; 命名方案的元素。为此,您可以轻松编写 XSD 并从中生成 JAXB 类。

标签: java xml xsd jaxb


【解决方案1】:

虽然有一些方法可以处理具有结构化名称(例如数字后缀)的元素,但

确实应该修复底层 XML 设计test_1 应该是 test)。

【讨论】:

    【解决方案2】:

    为了完整起见,这里是使用 XSLT 将 &lt;test_N&gt; 输入转换为 &lt;test id="N"&gt; 样式的完整工作示例

    <tests>
        <test_1>
            <foo bar="baz" />
        </test_1>
        <test_2>
            <foo bar="baz" />
        </test_2>
        <test_1234>
            <foo bar="baz" />
        </test_1234>
        <other>
            <foo></foo>
        </other>
    </tests>
    

    XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()" />
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*[substring(name(), 1, 5) = 'test_']">
            <xsl:element name="test">
                <xsl:attribute name="id"><xsl:value-of select="substring(name(), 6, string-length(name()) - 5)" /></xsl:attribute>
                <xsl:copy-of select="node()" />
            </xsl:element>
        </xsl:template>
    
    </xsl:stylesheet>
    

    代码

    File input = new File("test.xml");
    File stylesheet = new File("test.xsl");
    
    StreamSource stylesource = new StreamSource(stylesheet);
    Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
    StringWriter writer = new StringWriter();
    transformer.transform(new StreamSource(input), new StreamResult(writer));
    
    System.out.println(writer);
    

    输出

    <?xml version="1.0" encoding="UTF-8"?>
    <tests>
        <test id="1">
            <foo bar="baz"/>
        </test>
    
        <test id="2">
            <foo bar="baz"/>
        </test>
    
        <test id="1234">
            <foo bar="baz"/>
        </test>
    
        <other>
            <foo/>
        </other>
    </tests>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-12
      • 2014-01-20
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多