Как сравнить с несколькими строками в xslt
Для сравнения строкового значения xml с несколькими строками, я делаю следующее.
<xsl:if test="/Lines/@name = 'John' or /Lines/@name = 'Steve' or /Lines/@name = 'Marc' " >
Может ли кто-нибудь сказать мне, вместо того, чтобы использовать "или" в приведенном выше случае, как проверить, существует ли строка в наборе строк с помощью xslt.
Спасибо.
Ответы
Ответ 1
Три способа сделать это:
- Использовать строку с строкой (или другим подходящим символом)
...
<xsl:template match=
"Lines[contains('|John|Steve|Mark|',
concat('|', @name, '|')
)
]
">
<!-- Appropriate processing here -->
</xsl:template>
0,2. Протестировать внешний параметр. Если параметр не установлен снаружи, и мы используем XSLT 1.0, то функция расширения xxx:node-set()
должна использоваться для преобразования его в обычный node -set, прежде чем обращаться к своим дочерним элементам
<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="*"/>
<!-- externally-specified parameter -->
<xsl:param name="pNames">
<n>John</n>
<n>Steve</n>
<n>Mark</n>
</xsl:param>
<xsl:template match="Lines">
<xsl:if test="@name = $pNames/*">
<!-- Appropriate processing here -->
</xsl:if>
</xsl:template>
</xsl:stylesheet>
0,3. В XSLT 2.0 сравнивается с последовательностью строк
<xsl:template match="Lines[@name=('John','Steve','Mark')]">
<!-- Appropriate processing here -->
</xsl:template>
Ответ 2
Только XSLT 2.0: <xsl:if test="/Lines/@name = ('John', 'Steve', 'Marc')">
С XSLT 1.0 вы не можете написать буквенное выражение, представляющее последовательность строк или набор строк, но если вы знаете значения букв, вы можете построить набор узлов, например.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:data="http://example.com/data"
exclude-result-prefixes="data">
<data:data xmlns="">
<value>John</value>
<value>Steve</value>
<value>Marc</value>
</data:data>
<xsl:variable name="values" select="document('')/xsl:stylesheet/data:data/value"/>
<xsl:template match="...">
<xsl:if test="/Lines/@name = $values">..</xsl:if>
</xsl:template>
</xsl:stylesheet>
Ответ 3
Yep - я использую подстроку - поместите все ваше имя в строку - xsl: variable - тогда, если содержит true, имя есть
например.
<xsl:variable name="months">**janfebmaraprmajjunjulaugsepoktnovdec</xsl:variable>
<xsl:if test="contains($months,'feb')"> do stuff ...
Ответ 4
XPath имеет выражение some $x in (1,2,..) satisfies $x>10
, которое может быть полезно для этого. См.: http://www.java2s.com/Code/XML/XSLT-stylesheet/everyandsomeoperator.htm
Ответ 5
Для слов, разделенных пробелами, вы можете использовать index-of(tokenize("list of allowed", "\s+"), "needle"))
или match
, чтобы идти с регулярными выражениями, хотя я уверен, что есть что-то умнее этого.
Ответ 6
Другие возможности:
XPath 2.0 (XSLT 2.0)
matches(/Lines/@name, 'John|Steve|Marc')
В XSLT 1.0 у вас есть аналогичная функция matches
, предоставляемая EXSLT.
Примечание
Это не точное совпадение со строкой, а совпадение регулярных выражений, которое в вашем случае кажется подходящим в любом случае.