Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查找嵌套XML标记的索引_Java_Xpath - Fatal编程技术网

Java 查找嵌套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

假设我有这样一个XML:

<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的索引时的行为完全相同。你还有其他担心吗?是的,就是这样。明亮的是的,这个有效。非常感谢你。我才意识到我的已经起作用了,但没关系。有一些外界的意见总是好的。