【问题标题】:XPath - retrieve multiple values from different paths based on same conditionXPath - 基于相同条件从不同路径检索多个值
【发布时间】:2013-01-08 22:50:15
【问题描述】:

这是我的 XML

<root>
   <entry id="1">
      <value name="ID">11</value>
      <value name="ENABLE">0</value>
      <value name="NAME">USER1</value>
   </entry>
   <entry id="2">
      <value name="ID">11</value>
      <value name="ENABLE">0</value>
      <value name="NAME">USER2</value>
   </entry>
   <entry id="3">
      <value name="ID">12</value>
      <value name="ENABLE">0</value>
      <value name="NAME">USER1</value>
   </entry>
</root>

我需要一个 XPath 查询来检索 id11 的所有名称。

我试过了:

String xpath = "/root/entry/value[@name=ID/text()='11']/value[@name='NAME']";
String xpath = "/root/entry/value[@name=ID/text()='11']/NAME";

谁能告诉我查询中有什么问题?

编辑:

预期输出:

USER1
USER2

这两个都有 ID = 11

【问题讨论】:

  • 请举例说明预期输出。返回所有“名称”是什么意思?
  • 我的预期输出是 USER1 和 USER2,因为它们的 ID=11
  • 请参阅我的帖子,了解访问所有匹配节点而不是第一个节点所需的 Java 代码。

标签: xml xpath xml-parsing


【解决方案1】:

这将是正确的路径:

/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']

要检索节点列表,您需要使用带有 returnType 参数的 xPath.evaluate() 版本:

InputSource document = new InputSource(new FileInputStream("user1.xml"));
String xpath = "/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']";
NodeSet result = (NodeSet)xPath.evaluate(xpath, document, XPathConstants.NODESET); 
for(int index = 0; index < result.getLength(); index ++) {      
    Node node = result.item(index);
    String name = node.getNodeValue();
}

【讨论】:

  • @Abi 对不起,我有一个额外的斜线。请立即尝试。
【解决方案2】:

用途:

//entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']

【讨论】:

    【解决方案3】:

    使用

    /*/*[*[@name='ID'] = 11]/*[@name='NAME']
    

    基于 XSLT 的验证

    <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:copy-of select="/*/*[*[@name='ID'] = 11]/*[@name='NAME']"/>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于提供的 XML 文档时

    <root>
        <entry id="1">
            <value name="ID">11</value>
            <value name="ENABLE">0</value>
            <value name="NAME">USER1</value>
        </entry>
        <entry id="2">
            <value name="ID">11</value>
            <value name="ENABLE">0</value>
            <value name="NAME">USER2</value>
        </entry>
        <entry id="3">
            <value name="ID">12</value>
            <value name="ENABLE">0</value>
            <value name="NAME">USER1</value>
        </entry>
    </root>
    

    计算 XPath 表达式,并将计算结果(所有选定节点)复制到输出

    <value name="NAME">USER1</value>
    <value name="NAME">USER2</value>
    

    【讨论】:

    • 谢谢,这行得通,但 XSL 是唯一的方法吗?无法使用普通 XPath 完成?因为当我尝试在我的类中使用该 Xpath 时,它只返回 user1
    • @Abi Dimitre 的示例和我的示例都应该找到 USER1 和 USER2。如果您只获得一个值,那么您应用 XPath 的方式就是错误的。请向我们展示您的实际代码。
    • @JLRishe - 是的,这可能是错误,代码是 String xpath = "/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME' ]";字符串结果 = xPath.evaluate(xpath, new InputSource(new FileInputStream("user1.xml")));
    • @abi,evaluate() 的结果很可能是 Object - 并且需要转换为节点列表。您的错误是您将其分配给字符串。我不知道您使用的是什么 XPath API(PL 似乎是 Java)——请仔细阅读文档并查看任何可用的代码示例,以便您可以更正当前代码。
    • 我的错!!!没有意识到我在阅读结果部分时搞砸了。非常感谢您的所有回答
    【解决方案4】:

    试试这个,

    String xpath = "/root/entry[value[@name='ID' and text()='11']]/value[@name="NAME"]";

    【讨论】:

    • 不,我得到 11 作为输出
    • 我缺少 NAME 部分,现在检查一下
    • 我只返回一个用户值
    【解决方案5】:
    /root/entry[value[@name="ID" and .=11]]/value[@name="NAME"]
    

    /root/entry/value[@name="ID" and .=11]/../value[@name="NAME"]
    

    /descendant::entry[value=11 and value/@name="ID"]/value[@name="NAME"]
    

    //value[.=11]/@name[.="ID"]/ancestor::entry/value[@name="NAME"]
    

    或许多其他变体

    【讨论】:

    • 第一个选项 - 无限循环。第二个选项 - 只返回一个用户 USER1
    • 第四个选项也只返回一个值
    猜你喜欢
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    相关资源
    最近更新 更多