是否可以选择节点属性值中的字符串/字符序列重现次数为“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'字符串出现两次。
答案 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)。