Java 查找嵌套XML标记的索引
假设我有这样一个XML:Java 查找嵌套XML标记的索引,java,xpath,Java,Xpath,假设我有这样一个XML: <body> <nested attr="bla"> <name>foo</name> </nested> <nested attr="blub"> <name>bar</name> </nested> <nested attr="bli
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>bar</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
这对于从属性attr
获取索引非常有效,如下所示:
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>bar</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
getIndex(“/body/nested/@attr”,“blub”)
但我不知道如何对嵌套值执行此操作。如果我使用/body/nested/name
,那么它显然只会计算nested
中的name
标记,这不是我想要的
我如何解决这个问题,或者通过更改Java代码,或者甚至使用特殊的XPath表达式?如果我正确理解了您的问题,您希望在您的代码中包含
标记的索引,请查看下面的代码
public static void main(String[] args) throws TransformerException, SAXException, IOException, ParserConfigurationException {
String xmlString = "<body>\r\n" +
" <nested attr=\"bla\">\r\n" +
" <name>foo</name>\r\n" +
" </nested>\r\n" +
" <nested attr=\"blub\">\r\n" +
" <name>bar</name>\r\n" +
" </nested>\r\n" +
" <nested attr=\"bli\">\r\n" +
" <name>baz</name>\r\n" +
" </nested>\r\n" +
"</body>";
CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xmlString)));
NodeList list = cachedXPathAPI.selectNodeList(document, "/body/nested");
for(int i=0; i<list.getLength(); i++ ) {
String value = list.item(i).getAttributes().getNamedItem("attr").getTextContent();
System.out.println(list.item(i).getNodeName()+" @Index "+i+" attr:: "+value);
}
}
只需计算此XPath表达式:
count(/*/*[name='bar']/preceding-sibling::*) + 1
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>bar</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>barr</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
基于XSLT的验证:
count(/*/*[name='bar']/preceding-sibling::*) + 1
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>bar</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>barr</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
以下转换仅计算XPath表达式并输出此计算的结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select="count(/*/*[name='bar']/preceding-sibling::*) +1"/>
</xsl:template>
</xsl:stylesheet>
这是前面的XPath表达式,乘以另一个XPath表达式(在其左侧),如果没有满足筛选谓词的元素,则计算结果为0
,否则计算结果为1
基于XSLT的验证表明,如果存在令人满意的元素,则此XPath表达式的计算结果为正确的基于1的索引值;如果不存在此类元素,则计算结果为0
。在这里,我们利用了隐式转换number(false())
是0
,而number(true())
是1
下面是后一个示例:
count(/*/*[name='bar']/preceding-sibling::*) + 1
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>bar</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
<body>
<nested attr="bla">
<name>foo</name>
</nested>
<nested attr="blub">
<name>barr</name>
</nested>
<nested attr="bli">
<name>baz</name>
</nested>
</body>
产生了所需的正确结果:
0
已经发布了一个答案,请告诉我我的理解是否正确,解决方案是否正确。似乎您的评论被证明是错误的,在没有元素与筛选器匹配的情况下XPath表达式解决方案失败?如果是这样的话,你会承认这一点吗?我以前见过前面的兄弟姐妹方法。问题是第一个元素和一个根本不在XML中的元素的结果是一样的。两个都没有兄弟姐妹,因此将输出0(或1)。这是最优雅的方式though@geanakuch:我更新了答案,新的XPath表达式正确处理了这种情况。如果存在令人满意的元素,则返回正确的基于1的索引,否则返回0
——与index-of()
函数使用基于1的索引时的行为完全相同。你还有其他担心吗?是的,就是这样。明亮的是的,这个有效。非常感谢你。我才意识到我的已经起作用了,但没关系。有一些外界的意见总是好的。