3

是否可以在节点的属性值中选择具有“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' 字符串出现两次。

4

3 回答 3

6

如果您在 XPath 2.0 中,count(tokenize(., 'IF'))=3则将测试 IF 是否出现两次。

于 2012-09-06T13:20:11.570 回答
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')
          )
  ]
于 2012-09-06T13:23:43.677 回答
2

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

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

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

编辑:正如另一位汤姆指出的那样,这将匹配具有两个或多个“IF”的 ID。要使其仅匹配恰好具有两个“IF”的 ID,您需要

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

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

于 2012-09-06T11:39:30.063 回答