Хотя из этого вопроса совершенно не ясно, что вы хотите сделать, вот ответ на часть этого вопроса:
Возможно ли что-то подобное, используя
XSLT / XPath 1.0? Я знаю, что 2.0 имеет
функция токенизации, которая будет
идеально подходит для этого, но, к сожалению,
CMS, с которой я работаю, еще не
поддержка 2.0.
Токенизация была сделана в XSLT 1.0 в течение многих лет. Несмотря на то, что можно написать собственный рекурсивный шаблон для токенизации строки, хорошо помнить, что такое решение уже доступно в библиотеке FXSL и гарантированно работает, оно более мощное, чем типичная реализованная токенизация, и не имеет известных ошибки - просто готов к использованию.
Это шаблон str-split-to-words
, и вот один типичный пример его использования :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:import href="strSplit-to-Words.xsl"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="vwordNodes">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="/"/>
<xsl:with-param name="pDelimiters"
select="', 	 '"/>
</xsl:call-template>
</xsl:variable>
<xsl:apply-templates select="ext:node-set($vwordNodes)/*"/>
</xsl:template>
<xsl:template match="word">
<xsl:value-of select="concat(position(), ' ', ., ' ')"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к следующему документу XML :
<t>Sorry, kid, first-borns really are smarter.
First-borns are typically smarter, while
younger siblings get better grades and
are more outgoing, the researchers say</t>
желаемый, правильный результат получается :
1 Sorry
2 kid
3 first-borns
4 really
5 are
6 smarter.
7 First-borns
8 are
9 typically
10 smarter
11 while
12 younger
13 siblings
14 get
15 better
16 grades
17 and
18 are
19 more
20 outgoing
21 the
22 researchers
23 say
Обратите внимание , что шаблон принимает параметр с именем pDelimiters
, в котором можно указать несколько разделителей.
Обновление : Я наконец понял, что ОП хочет с этой проблемой. Вот мое решение, которое снова использует шаблон str-split-to-words
для токенизации:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
>
<xsl:import href="strSplit-to-Words.xsl"/>
<!-- to be applied upon: test-strSplit-to-Words2.xml -->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="vCategories">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select=
"/*/select-criteria/Categories"/>
<xsl:with-param name="pDelimiters"
select="'|'"/>
</xsl:call-template>
</xsl:variable>
<xsl:apply-templates select="*/pages/Page">
<xsl:with-param name="pCategories" select=
"ext:node-set($vCategories)"/>
<xsl:with-param name="pMatchType" select=
"*/select-criteria/MatchType"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Page">
<xsl:param name="pCategories"/>
<xsl:param name="pMatchType" select="any"/>
<xsl:variable name="vDecoratedCurrent"
select="concat('|', @CategoryIds, '|')"/>
<xsl:variable name="vSelected" select=
"$pCategories/*
[$pMatchType = 'any']
[contains($vDecoratedCurrent,
concat('|', ., '|')
)
][1]
or
not($pCategories/*[not(contains($vDecoratedCurrent,
concat('|', ., '|')
)
)
][1]
)
"/>
<xsl:copy-of select="self::node()[$vSelected]"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к этому документу XML:
<t>
<select-criteria>
<Categories>851|849</Categories>
<MatchType>any</MatchType>
</select-criteria>
<pages>
<Page CategoryIds="848|849|850|851">Page 1</Page>
<Page CategoryIds="849|850|">Page 2</Page>
<Page CategoryIds="848|850|">Page 3</Page>
<Page CategoryIds="848|849|850|851">Page 4</Page>
<Page CategoryIds="848|850|851">Page 5</Page>
<Page CategoryIds="848|849|850">Page 6</Page>
</pages>
</t>
желаемый, правильный результат получается :
<Page CategoryIds="848|849|850|851">Page 1</Page>
<Page CategoryIds="849|850|">Page 2</Page>
<Page CategoryIds="848|849|850|851">Page 4</Page>
<Page CategoryIds="848|850|851">Page 5</Page>
<Page CategoryIds="848|849|850">Page 6</Page>
Когда в документе XML мы указываем :
<MatchType>all</MatchType>
мы снова получаем желаемый, правильный результат :
<Page CategoryIds="848|849|850|851">Page 1</Page>
<Page CategoryIds="848|849|850|851">Page 4</Page>