Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 计算XPath属性中字符串的出现次数_Xml_String_Xpath - Fatal编程技术网

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

Xml 计算XPath属性中字符串的出现次数,xml,string,xpath,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"> </Mod

是否可以在节点属性的值中选择字符串/字符序列重复出现次数为“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为(attribute)的节点,该节点的“IF”字符串出现两次。

我不知道使用XPath计算匹配数的方法,但您可以使用substring after函数进行欺骗:

//*[contains(substring-after(@id, "IF"), "IF")]
这将查找在字符串“IF”(相当于“IF”两次)之后包含字符串“IF”的ID属性的所有元素。它不像我想的那样可读,但它很有效。我使用这个交互式xpath测试仪进行了测试:

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

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

但这在我看来非常难看(它是匹配具有2个或更多“如果”的ID,而不是具有3个或更多“如果”的ID)。

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

使用此XPath表达式

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

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

这也将匹配字符串,其中“IF”出现两次以上。ID的格式总是相同的吗?两个字母后跟一个数字和一个点的序列?如果是,您可以使用XPath 2.0函数
matches
,它将字符串与正则表达式匹配。。。只要使用XPath 2.0是一个选项,因为我使用的是XPath 1.0,解析器是pugi,所以我不能使用这个解决方案,但子字符串after对我来说非常有效。谢谢凯先生和诺瓦切夫先生
  /*/*
  [contains(@ID, 'IF')
  and contains(substring-after(@ID, 'IF'), 'IF')
  and not(contains(
              substring-after(substring-after(@ID, 'IF'),'IF'),
              'IF')
          )
  ]