#linux #xslt
#linux #xslt
Вопрос:
У меня есть массив строк в файле .xsl, теперь я должен использовать каждую строку, разделенную пробелами, по-разному. Как я могу получить строки?
У меня есть следующий массив строк:
strarray="hw.oh.xml hg.hd.gnl th.ik.lkj"
Я должен получить «hw.oh.xml строки «», «hg.hd.gnl», «th.ik.lkj» отдельно, чтобы выполнить с ними какую-то операцию.
Как я могу это сделать?
Комментарии:
1. Хороший вопрос, 1. Смотрите мой ответ для трех полных решений. 🙂
2. Замечательно… Большое спасибо @ Dimitre Novatchev за ваши ответы. Но в моем случае у меня есть переменная, которая содержит, как я показал в моей проблеме. тогда как с этим справиться. и он содержит более 10 строк. Заранее спасибо .. я использую версию = «1.0» xslt.
3. Добро пожаловать. Особенно в вашем случае, я добавил четвертое решение к своему ответу.
Ответ №1:
Есть много способов сделать это:
I. Использование XPath substring-before()
и substring-after()
функций:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vStrArray" select="'hw.oh.xml hg.hd.gnl th.ik.lkj'"/>
<xsl:template match="/">
<xsl:value-of select="substring-before($vStrArray, ' ')"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="substring-before(substring-after($vStrArray, ' '),' ')"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="substring-after(substring-after($vStrArray, ' '),' ')"/>
<xsl:text>amp;#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к любому XML-документу (не используется), получается требуемый результат (каждый элемент из «массива»):
hw.oh.xml
hg.hd.gnl
th.ik.lkj
Этот метод может быстро стать чрезмерно сложным и не рекомендуется, за исключением «массивов», состоящих всего из 2-3 элементов.
II. Представление «массива» в виде XML-документа в XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:array>
<item>hw.oh.xml</item>
<item>hg.hd.gnl</item>
<item>th.ik.lkj</item>
</my:array>
<xsl:variable name="vStrArray"
select="document('')/*/my:array/*"/>
<xsl:template match="/">
<xsl:value-of select="$vStrArray[1]"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="$vStrArray[2]"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="$vStrArray[3]"/>
<xsl:text>amp;#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к тому же XML-документу (любому), получается требуемый правильный результат:
hw.oh.xml
hg.hd.gnl
th.ik.lkj
Я рекомендую этот метод представления «массива» — для приложений XSLT 1.0.
III. XSLT 2.0 / XPath 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:variable name="vStrArray"
select="'hw.oh.xml', 'hg.hd.gnl', 'th.ik.lkj'"/>
<xsl:template match="/">
<xsl:sequence select=
"for $i in 1 to count($vStrArray)
return
concat($vStrArray[$i], 'amp;#xA;')
"/>
</xsl:template>
</xsl:stylesheet>
Результат:
hw.oh.xml
hg.hd.gnl
th.ik.lkj
ОБНОВЛЕНИЕ: Оператор прокомментировал, что он застрял с начальным представлением разделенных пробелами значений, содержащихся в одной строке.
IV. Преобразуйте строку значений, разделенных пробелом, в XML-фрагмент для удобства использования.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vStrArray" select="'hw.oh.xml hg.hd.gnl th.ik.lkj'"/>
<xsl:variable name="vrtfDoc">
<xsl:call-template name="makeIndex">
<xsl:with-param name="pText" select="$vStrArray"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vStrIndex" select="ext:node-set($vrtfDoc)/*"/>
<xsl:template match="/">
<xsl:value-of select="$vStrIndex[1]"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="$vStrIndex[2]"/>
<xsl:text>amp;#xA;</xsl:text>
<xsl:value-of select="$vStrIndex[3]"/>
</xsl:template>
<xsl:template name="makeIndex">
<xsl:param name="pText"/>
<xsl:if test="string-length($pText)>0">
<item>
<xsl:value-of select=
"substring-before(concat($pText,' '), ' ')"/>
</item>
<xsl:call-template name="makeIndex">
<xsl:with-param name="pText" select=
"substring-after($pText,' ')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Это преобразование создает XML-фрагмент из строки, в котором каждый <item>
элемент содержит только одно из строковых значений. Тогда его использование такое же, как если бы это был массив.