【问题标题】:How to select the node with grand-grandchild node that has particular value如何选择具有特定值的孙子节点的节点
【发布时间】:2014-10-17 16:50:20
【问题描述】:

您好,我只想获取值为“123abc”的元素 A。我都试过了,但都失败了。

//包装/A[A/B/C/. = 123abc]

//包/A[包含(A/B/C,123abc)]

我希望它返回这个:

  <A>
    <System mtm="8742" os="Windows XP" oslang="en" />
    <System mtm="2055" os="Windows XP" oslang="jp" />
    <A>
       <B>
           <C>123abc</C>
           <C>789</C>
           <C>567</C>
       </B>
     </A>
    </A>

要运行查询的示例 xml:

<?xml version="1.0" encoding="UTF-8"?>
<Database version="300">
<Package>  
<A>
    <System mtm="8742" os="Windows XP" oslang="en" />
    <System mtm="2055" os="Windows XP" oslang="jp" />
    <A>
       <B>
           <C>123abc</C>
           <C>789</C>
           <C>567</C>
       </B>
    </A>
</A>
</Package>
<Package>  
<A>
    <System mtm="8742" os="Windows XP" oslang="en" />
    <System mtm="2055" os="Windows XP" oslang="jp" />
    <A>
       <B>
           <C>efg123</C>
           <C>789</C>
           <C>567</C>
       </B>
    </A>
</A>
</Package>
</Database>

你可以在这里测试你的答案:http://www.freeformatter.com/xpath-tester.html#ad-output

添加了我正在尝试处理的实际 xml,但是如果特殊字符被转义,它将不起作用吗?

我正在尝试处理的实际xml如下,我已经尝试过

//TableSection/SectionItem[SectionItem/Cell/. =“00-18-E7-17-48-64”]

//TableSection/SectionItem[contains(SectionItem/Cell,"00-18-E7-17-48-64")]

      <TableSection name="SNMP Devices" IsTreeFormat="true">
       <SectionProperties>
        <Column id="1" Name="IP Address" />
        <Column id="2" Name="Description" />
       </SectionProperties>
       <SectionItem>
        <Cell columnid="1">
         192.168.99.54
        </Cell>
        <Cell columnid="2">
         WMI XScan
        </Cell>
        <SectionItem>
         <Cell columnid="1">
          ScanType
         </Cell>
         <Cell columnid="2">
          WMIScan
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          Device description
         </Cell>
         <Cell columnid="2">
          WMI dscription
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          MACAddress
         </Cell>
         <Cell columnid="2">
          00-18-E7-17-48-64
         </Cell>
        </SectionItem>
       </SectionItem>
       <SectionItem>
        <Cell columnid="1">
         192.168.99.55
        </Cell>
        <Cell columnid="2">
         WMI XScan
        </Cell>
        <SectionItem>
         <Cell columnid="1">
          ScanType
         </Cell>
         <Cell columnid="2">
          WMIScan
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          Device description
         </Cell>
         <Cell columnid="2">
          WMI dscription
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          MACAddress
         </Cell>
         <Cell columnid="2">
          90-2B-34-64-16-9D
         </Cell>
        </SectionItem>
       </SectionItem>
       <SectionItem>
        <Cell columnid="1">
         192.168.99.107
        </Cell>
        <Cell columnid="2">
         VMWare : &quot;navvms08.Crest.local&quot;
        </Cell>
        <SectionItem>
         <Cell columnid="1">
          MACAddress
         </Cell>
         <Cell columnid="2">
          00-07-E9-0D-05-C5
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          Device identifier
         </Cell>
         <Cell columnid="2">
          1.3.6.1.4.1.6876.4.1
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          Device name
         </Cell>
         <Cell columnid="2">
          &quot;navvms08.Crest.local&quot;
         </Cell>
        </SectionItem>
        <SectionItem>
         <Cell columnid="1">
          Device description
         </Cell>
         <Cell columnid="2">
          &quot;VMware ESXi 5.5.0 build-1623387 VMware, Inc. x86_64&quot;
         </Cell>
        </SectionItem>
       </SectionItem>
      </TableSection>

【问题讨论】:

    标签: xpath xquery


    【解决方案1】:

    在原始示例中,您需要引用比较字符串。这两种方法都有效:

    //Package/A[A/B/C/. = "123abc"]
    
    //Package/A[contains(A/B/C,"123abc")]
    

    您正在运行的实际 XML 的查询应该是:

    //TableSection/SectionItem[SectionItem/Cell[contains(.,"00-18-E7-17-48-64")]]
    

    问题:

    //TableSection/SectionItem[SectionItem/Cell/. = "00-18-E7-17-48-64"]
    

    是文本内容必须完全匹配,而 XML 有前导和尾随空格。

    问题:

    //TableSection/SectionItem[contains(SectionItem/Cell,"00-18-E7-17-48-64")]
    

    contains() 只在//TableSection/SectionItem 中的第一个SectionItem/Cell 中查找,而不是其中的any SectionItem/Cell 来查找文本。

    【讨论】:

    • 谢谢保罗。我已将我正在尝试处理的实际 xml 添加到原始问题中,因为我仍然无法使查询正常工作。非常感谢有人能帮我解决这个问题,因为我已经花了几个小时。
    【解决方案2】:

    对于第一个示例,您没有引用要比较的字符串。此外,您不需要额外的 /. 表达式,因为无论如何都会将节点原子化规则应用于字符串比较。

    XPath //Package/A[A/B/C = "123abc"] 就足够了。

    如果您想对C 的文本内容进行部分匹配,那么您可以使用//Package/A[A/B/C/contains(., "123abc")]。你确实需要.,因为你想找到一个A元素,它有一个Cgrand-daughter元素,其中包含文本123abc. 指的是当前上下文,这里是一个单独的 C 元素。 否则,如果您执行了A/B/contains(C, "123abc"),您将收到类型错误,因为您有多个C 元素并且fn:contains 无法对序列进行操作。


    对于第二个示例,没有包含的示例是空格问题,您可以使用contains 解决此问题,但是您的包含尝试对序列进行操作。相反,你应该把它改成这样:

    //TableSection/SectionItem[SectionItem/Cell/contains(., "00-18-E7-17-48-64")]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 2016-02-04
      • 1970-01-01
      • 2014-07-06
      相关资源
      最近更新 更多