计算XPath属性中字符串的出现次数

时间:2012-09-06 10:14:37

标签: xml string xpath

是否可以选择节点属性值中的字符串/字符序列重现次数为“n”的节点?

例如:

<IOCFG xmlns="http://www.br-automation.com/AR/IO" Version="2.0">
    <Module ID="$root.IO" Hardware="X20CP1484">
    </Module>
    <Module ID="$rot.IO" Hardware="X20CP1484">
    </Module>
    <Module ID="$rt.IO" Hardware="X20CP1484">
    </Module>
    **<Module ID="IF3.IF1.ST9" Hardware="Hello"/>**
    <Module ID="IF3.IF2.IF3.ST9" Hardware="Bye"/>
    **<Module ID="IF3.IF2.ST1" Hardware="hai"/>**
</IOCFG>

从上面的文件我只能选择ID(属性)的节点,其中'IF'字符串出现两次。

3 个答案:

答案 0 :(得分:5)

如果您使用的是XPath 2.0,那么count(tokenize(., 'IF'))=3将测试IF是否出现两次。

答案 1 :(得分:3)

使用此XPath表达式

/*/*
   [translate(@ID, translate(@ID, 'IF', ''), '')='IFIF']

基于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=
     "/*/*
      [translate(@ID, translate(@ID, 'IF', ''), '')='IFIF']

     "/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<IOCFG xmlns="http://www.br-automation.com/AR/IO" Version="2.0">
<Module ID="$root.IO" Hardware="X20CP1484">
</Module>
<Module ID="$rot.IO" Hardware="X20CP1484">
</Module>
<Module ID="$rt.IO" Hardware="X20CP1484">
</Module>
**<Module ID="IF3.IF1.ST9" Hardware="Hello"/>**
<Module ID="IF3.IF2.IF3.ST9" Hardware="Bye"/>
**<Module ID="IF3.IF2.ST1" Hardware="hai"/>**
</IOCFG>

评估XPath表达式并将所选元素复制到输出中:

<Module xmlns="http://www.br-automation.com/AR/IO" ID="IF3.IF1.ST9" Hardware="Hello"/>
<Module xmlns="http://www.br-automation.com/AR/IO" ID="IF3.IF2.ST1" Hardware="hai"/>

请注意

这是一个粗略解决方案,它假定ID属性的值具有某些属性(如提供的XML中所示)。如果这个假设被破坏,相同的XPath表达式可能不会产生正确的结果。

一个精确的XPath 1.0表达式,它只选择ID属性包含字符串"IF"两次的元素:

  /*/*
  [contains(@ID, 'IF')
  and contains(substring-after(@ID, 'IF'), 'IF')
  and not(contains(
              substring-after(substring-after(@ID, 'IF'),'IF'),
              'IF')
          )
  ]

答案 2 :(得分:1)

我不知道使用XPath计算匹配的方法,但你可以使用substring-after函数作弊:

//*[contains(substring-after(@id, "IF"), "IF")]

这将查找具有ID属性的所有元素,该属性在字符串“IF”之后包含字符串“IF”(相当于“IF”两次)。它不像我想的那样可读,但它有效。我使用这个交互式xpath测试器测试了它:http://ponderer.org/download/xpath/

编辑:正如其他Tom指出的那样,这将匹配具有两个或更多“IF”的ID。要使它只匹配具有两个“IF”的ID,您需要

//*[contains(substring-after(@id, "IF"), "IF") and not(contains(substring-after(substring-after(@id, "IF"), "IF"), "IF"))]

但这对我来说看起来很丑陋(它的匹配ID有2个或更多“IF”但不是具有3个或更多“IF”的ID)。