XSL: построить массив из строки с разделителями
У меня есть строка, в которой данные разделяются разделителем типа "|"
и присутствует в переменной.
Я хотел бы создать массив в XSL, разделив указанную выше строку на основе разделителя и хотел бы получить доступ к тому же в цикле for.
Пожалуйста, помогите мне в этом отношении.
Пожалуйста, дайте мне знать, если кому-то нужна дополнительная информация.
String is "Test1|Test2|Test3|Test4"
и хотел бы получить переменную TEMP
, которая будет массивом данных из строки и хотела бы получить доступ как TEMP[index]
.
Я попытался использовать функцию tokenize после ввода от участников форума, чтобы получить значения из строки, но не был успешным. Я не получаю строковые значения в цикле.
<xsl:variable name="temp" xmlns:str="http://exslt.org/strings" select="str:tokenize(normalize-space(' Test1$,$Test2$,$Test3$,$Test4 '),'$,$')"/>
<xsl:for-each xmlns:str="http://exslt.org/strings" select="str:split(normalize-space(' 1$,$2$,$3$,$4$,$5$,$6 '),'$,$')">
<xsl:variable name="index" select="position()"/>
<xsl:value-of select="$temp[$index]"/>
</xsl:for-each>
С уважением,
Lakshman
Ответы
Ответ 1
Строка "Test1|Test2|Test3|Test4"
и хочет получить переменную TEMP
, который будет массивом данных из строки и хотел бы для доступа к TEMP[index]
.
+1 для хорошего вопроса.
Преобразование XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vrtfTokens">
<xsl:apply-templates/>
</xsl:variable>
<xsl:variable name="vTokens" select=
"ext:node-set($vrtfTokens)/*"/>
<xsl:template match="/">
<xsl:for-each select=
"document('')//node()[not(position() > count($vTokens))]
">
<xsl:variable name="vPos" select="position()"/>
<xsl:copy-of select="$vTokens[$vPos+0]"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText)">
<xsl:variable name="vToken" select=
"substring-before(concat($pText,'|'), '|')"/>
<s><xsl:value-of select="$vToken"/></s>
<xsl:call-template name="split">
<xsl:with-param name="pText" select=
"substring-after($pText, '|')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
при применении к этому XML-документу:
<t>Test1|Test2|Test3|Test4</t>
создает переменную vTokens
, которая содержит элементы с именем s
, каждый из которых имеет в качестве своего единственного текстового дочернего токена из строки '|' -delimited "Test1|Test2|Test3|Test4"
.
Затем преобразование выводит каждый из этих элементов s
, используя "индекс".
Полученный, правильный результат получается:
<s>Test1</s>
<s>Test2</s>
<s>Test3</s>
<s>Test4</s>
Если нам нужны только сами маркеры (строки), мы будем использовать:
string($vTokens[someIndex])
Ответ 2
Это не будет массив, а последовательность, и у вас должен быть процессор XSLT 2.0. Вы можете использовать функцию tokenize()
:
<xsl:variable name="temp" as="xs:string*" select="tokenize('Test1|Test2|Test3|Test4','\|')"/>
Вы также можете передать строковую переменную в качестве первого аргумента tokenize.
Затем вы используете:
<xsl:value-of select="$temp[$index]"/>
EDIT: достичь этого в xslt 1.0 невозможно, если вы не используете какое-то расширение.
Ответ 3
Эта задача называется tokenizing, в XSLT 2.0 вы можете использовать tokenize('Test1|Test2|Test3|Test4', '\|')
, с XSLT 1.0 вы можете использовать расширение, например http://www.exslt.org/str/functions/tokenize/index.html.
Ответ 4
Я пробую это, я изменил код "Dimitre Novatchev" и работает для меня: (пожалуйста, извините меня за мой английский)
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:template match="/*">
<xsl:variable name="_keywords">
<xsl:call-template name="split-to-values">
<xsl:with-param name="_text" select="Keywords-comma-separated"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($_keywords)/value">
<xsl:variable name="_keyword" select="."/>
<!-- ANY CODE -->
</xsl:for-each>
</xsl:template>
<xsl:template match="text()" name="split-to-values">
<xsl:param name="_text"/>
<xsl:if test="string-length($_text)">
<xsl:variable name="_value" select="substring-before($_text, ',')"/>
<xsl:variable name="_next" select="substring-after($_text, ',')"/>
<value>
<xsl:value-of select="$_value"/>
</value>
<xsl:call-template name="split-to-values">
<xsl:with-param name="_text" select="$_next"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Я надеюсь, что это поможет вам
@Bugude ask
У меня есть строка, в которой данные разделяются разделителем типа "|" а также присутствует в переменной. Я хотел бы создать массив в XSL путем деления указанной строки на основе разделителя и хотел бы получить доступ к одному и тому же в цикле for
Тогда строка может быть: "alfa, beta, gama, delta"
Разделитель представлен в переменной:
<xsl:variable name="_delimiter">,</xsl:variable>
Я изменил шаблон как:
<xsl:template match="text()" name="split-to-values">
<xsl:param name="_text"/>
<xsl:param name="_delimiter"/>
<xsl:if test="string-length($_text)">
<xsl:variable name="_value" select="substring-before($_text, $_delimiter)"/>
<xsl:variable name="_next" select="substring-after($_text, $_delimiter)"/>
<value>
<xsl:value-of select="$_value"/>
</value>
<xsl:call-template name="split-to-values">
<xsl:with-param name="_text" select="$_next"/>
<xsl:with-param name="_delimiter" select="$_delimiter"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
И мы можем получить доступ к узлам как похожий массив с a для
<xsl:template match="/*">
<!-- _keyword as set a node -->
<xsl:variable name="_keywords">
<xsl:call-template name="split-to-values">
<xsl:with-param name="_text" select="'alfa,beta,gama,delta'"/>
<xsl:with-param name="_delimiter" select="$_delimiter"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($_keywords)/value">
<xsl:variable name="_keyword" select="."/>
<!-- ANY CODE -->
<xsl:value-of select="$_keyword"/>
</xsl:for-each>
</xsl:template>