简体   繁体   中英

Update variable value in XSLT for-each loop

I have this XML:

<Root>
  <Employee>
    <Name>Dash</Name>
    <Age>23</Age>
  </Employee>
  <Employee>
    <Name>Gwen</Name>
    <Age>22</Age>
  </Employee>
</Root>

And I need to convert to below XML using XSLT:

<Root>
  <Employee>
    <Name>Dash,Gwen</Name>
    <Age>23,22</Age>
  </Employee>
</Root>

I am using the for-each loop to get the values of the sub-nodes of the <Employee> node.The problem I am facing is I cannot figure out how to store the concatenated values in another temperoary variable in XSLT.I found on many sites that we cannot update the variables in the XSLT, so is there any alternative solution for this?

Will this do?

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
   <xsl:template match="Root">
      <Root>
         <Employee>
            <Name>
              <xsl:value-of select="Employee/Name" separator="," />
            </Name>
            <Age>
              <xsl:value-of select="Employee/Age" separator="," />
            </Age>
         </Employee>
      </Root>
   </xsl:template>
</xsl:stylesheet>

This is what I meant by " use a common template for both and avoid the code repetition ":

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Root">
    <Root>
        <Employee>
            <Name>
                <xsl:apply-templates select="Employee/Name"/>
            </Name>
            <Age>
                <xsl:apply-templates select="Employee/Age"/>
            </Age>
        </Employee>
    </Root>
</xsl:template>

<xsl:template match="Name|Age">
    <xsl:value-of select="."/>
    <xsl:if test="position()!=last()">
        <xsl:text>,</xsl:text>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

While I am here, let me also point out that this replaces a solid XML structure with a very problematic one. I am not sure what's the purpose of this transformation, but the result is an XML that could be very difficult to consume by downstream applications.

please try the following stylesheet:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>

    <xsl:template match="Root">
        <Root>
            <Employee>
                <Name>
                    <xsl:for-each select="Employee/Name">
                        <xsl:if test="position() &gt; 1">
                            <xsl:text>,</xsl:text>
                        </xsl:if>
                        <xsl:value-of select="."/>
                    </xsl:for-each>
                </Name>
                <Age>
                    <xsl:for-each select="Employee/Age">
                        <xsl:if test="position() &gt; 1">
                            <xsl:text>,</xsl:text>
                        </xsl:if>
                        <xsl:value-of select="."/>
                    </xsl:for-each>
                </Age>
            </Employee>
        </Root>
    </xsl:template>
</xsl:stylesheet>

or as an alternative,

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:strip-space elements="*"/>

    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <Root>
            <Employee>
                <xsl:apply-templates select="Root/Employee[1]"/>
            </Employee>
        </Root>
    </xsl:template>

    <xsl:template match="Employee[1]/Name|Employee[1]/Age">
        <xsl:variable name="curr_name" select="name()"/>
        <xsl:copy>
            <xsl:value-of select="."/>
            <xsl:for-each select="following::*[name()=$curr_name]">
                <xsl:text>,</xsl:text>
                <xsl:value-of select="."/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>


</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM