Как я могу разделить данные и хранить их в нескольких узлах в XSLT

#xml #xslt

Вопрос:

У меня есть следующие xml-данные:

 <?xml?> 
<data>
    <first>1,2,3,4</first>
    <second>A,B,C,D</second>
</data>
 

Как преобразовать его во что-то подобное с помощью XSLT

 <result>
    <first>1</first>
    <second>A</second>
</result>
<result>
    <first>2</first>
    <second>B</second>
</result>
<result>
    <first>3</first>
    <second>C</second>
</result>
<result>
    <first>4</first>
    <second>D</second>
</result>
 

Есть ли какое-нибудь решение? Пожалуйста, помогите, пожалуйста.

Комментарии:

1. Пожалуйста, укажите, какой процессор XSLT вы будете использовать.

Ответ №1:

Решение XSLT-2.0 может быть

 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
    <xsl:template match="/data">
        <xsl:variable name="first"  select="tokenize(first,',')" />
        <xsl:variable name="second" select="tokenize(second,',')" />
        <data>
            <xsl:for-each select="$first">
                <xsl:variable name="cur" select="position()" />
                <first><xsl:value-of select="." /></first>
                <second><xsl:value-of select="$second[$cur]" /></second>
            </xsl:for-each>
        </data>
    </xsl:template>
   
</xsl:stylesheet>
 

И его выход-это

 <?xml version="1.0" encoding="UTF-8"?>
<data>
    <first>1</first>
    <second>A</second>
    <first>2</first>
    <second>B</second>
    <first>3</first>
    <second>C</second>
    <first>4</first>
    <second>D</second>
</data>
 

И решение XSLT-1.0 будет более сложным — потребуется рекурсивный шаблон для разделения строк, разделенных запятыми.

Ответ №2:

Вот решение XSLT 3.0:

 <xsl:function name="f:process-pair">
  <xsl:param name="x"/>
  <xsl:param name="y"/>
  <result>
     <first>{$x}</first>
     <second>{$y}</second>
  </result>
</xsl:function>

<xsl:template match="data">
  <xsl:sequence select="for-each-pair(
               tokenize(first, ','), 
               tokenize(second, ','), 
               f:process-pair#2)"/>
</xsl:template>