我可以让下面的 xpath 表达式更简单吗:
//*[translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ,'abcdefghijklmnopqrstuvwxyz')='word1'
or translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ,'abcdefghijklmnopqrstuvwxyz')='word2']
使用:
//*[text()[starts-with(translate(., 'WORD', 'word'), 'word')
and substring(.,5) = 1 or substring(.,5) = 2]]
=================================
基于 XSLT 的验证:
这种转变:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//*[text()[starts-with(translate(., 'WORD', 'word'), 'word')
and substring(.,5) = 1 or substring(.,5) = 2]]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于此源 XML 文档时:
<t>
<a>
<b>Word2</b>
<c>word3</c>
<d>word1</d>
<e>Word11</e>
<f>Xxx</f>
</a>
</t>
产生想要的、正确的结果——仅将匹配 XPath 表达式的元素复制到输出:
<b>Word2</b>
<d>word1</d>
更新:在评论中,OP 澄清说他想要一个 XPath 1.0 表达式来检查给定字符串是否是其他两个给定字符串之一。
这是在 XPath 1.0 中执行此操作的一种方法:
contains(concat('|', $s1, '|', $s2, '|'), concat('|', $s, '|'))
我们检查给定字符串$s 的左+右连接是其他两个给定字符串$s1 和$s2 的连接中的子字符串(包含),因此相同的字符--@987654330 @ 是最左边、最右边和两个字符串之间的分隔符。
这里我们使用'|'作为分隔符,但任何已知不包含在$s 中的字符串都可以使用——例如?、$$$ 等。
那么上面已经提供的解决方案可以这样改写:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match=
"//*[text()[contains('|word1|word2|',
concat('|',translate(., 'WORD', 'word'), '|')
)]
]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
当此转换应用于同一个 XML 文档(上图)时,会产生相同的正确结果:
<b>Word2</b>
<d>word1</d>