I.Решение XSLT 1.0:
Это преобразование:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pIds">
<id>list</id>
<id>map</id>
</xsl:param>
<xsl:variable name="vIds" select=
"document('')/*/xsl:param[@name='pIds']/*"/>
<xsl:template match="group">
<xsl:if test=
"$vIds[. = current()/@id
or
starts-with(current()/@id, .)
and
substring-after(current()/@id, .)
=
floor(substring-after(current()/@id, .))
]
">
<!-- Processing here: -->
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
при применении к этому документу XML :
<t>
<group id="list"/>
<group id="list1"/>
<group id="listX"/>
<group id="list2"/>
<group id="map"/>
<group id="map123Z"/>
<group id="map1"/>
</t>
обрабатывает (в этом примере копирует) точно совпадающие узлы :
<group id="list"/>
<group id="list1"/>
<group id="list2"/>
<group id="map"/>
<group id="map1"/>
Пояснение :
Использование стандартных функций XPathstarts-with()
, substring-after()
и floor()
.
Простой тест, если строка преобразуется в целое число: floor($s) = $s
II.Решение XSLT 2.0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pIds" select="'list', 'map'"/>
<xsl:variable name="vIds" select=
"document('')/*/xsl:param[@name='pIds']/*"/>
<xsl:template match=
"group
[@id = $pIds
or
$pIds
[starts-with(current()/@id, .)
and
substring-after(current()/@id, .)
castable as
xs:integer
]
]
">
<!-- Processing here: -->
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Объяснение : Это решение очень похоже на решение XSLT 1.0 со следующими основными отличиями:
В XSLT 2.0 разрешено иметь ссылки на переменные / параметры в шаблоне сопоставления.Используя это, мы избегаем <xsl:if>
внутри тела шаблона.
Мы определяем параметр, чтобы он содержал последовательность желаемых строк.
Мы используем стандартный оператор XPath 2.0 castable as
.