如何选择具有特定值的孙子节点的节点

时间:2014-10-17 01:16:45

标签: xpath xquery

嗨,我只想获得价值为" 123abc"在里面。我试过了两次但都失败了。

  

//封装/ 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 /小区/。 =&#34; 00-18-E7-17-48-64&#34;]

     

// TableSection / SectionItem [含有(SectionItem /细胞,&#34; 00-18-E7-17-48-64&#34)]

      <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>

2 个答案:

答案 0 :(得分: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()仅查看SectionItem/Cell内的第一个//TableSection/SectionItem,而不是其中的任何 SectionItem/Cell来查找文字。

答案 1 :(得分:0)

对于第一个示例,您没有引用要比较的字符串。此外,您不需要额外的/.表达式,因为节点atomizaton规则将应用于字符串比较。

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

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


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

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