Можно ли упростить следующее выражение 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>
Обновление : в комментарии ОП пояснил, что он хочет выражение XPath 1.0, которое проверяет, является ли данная строкаявляется одной из двух других заданных строк или нет.
Вот один из способов сделать это в XPath 1.0 :
contains(concat('|', $s1, '|', $s2, '|'), concat('|', $s, '|'))
Мы проверяем, что левая + правая конкатенацияданной строки $s
является подстрокой (содержится) в конкатенации двух других указанных строк $s1
и $s2
, так что один и тот же символ - |
- самый левый, самый правыйи разделитель между тдве строки.
Здесь мы используем '|'в качестве разделителя, но может использоваться любая строка, о которой известно, что она не содержится в $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>