Xml 计算XPath属性中字符串的出现次数
是否可以在节点属性的值中选择字符串/字符序列重复出现次数为“n”的节点 例如: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
<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')
)
]