我已经通过以下格式解析了一些第三方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?
的<xs:any processContents="lax"/>
技术,但是这允许任何内容,而不是<test_<integer>
。我只想确认我没有错过一些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>
答案 0 :(得分:1)
虽然有办法处理具有结构名称的元素,例如数字后缀,
name()
或local-name()
使用字符串测试你 确实应该修复基础XML设计 (test_1
应该是test
)。
答案 1 :(得分:0)
为了完整性,这里是使用XSLT将<test_N>
输入转换为<test id="N">
样式的完整工作示例
<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>