简体   繁体   English

在XSLT for-each循环中更新变量值

[英]Update variable value in XSLT for-each loop

I have this XML: 我有这个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: 我需要使用XSLT转换为以下XML:

<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? 我正在使用for-each循环来获取<Employee>节点的子节点的值。我面临的问题是我无法弄清楚如何将串联的值存储在XSLT的另一个临时变量中。许多站点我们无法更新XSLT中的变量,那么有没有其他解决方案呢?

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 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. 当我在这里时,我还要指出,这用一个非常有问题的XML结构代替了坚实的XML结构。 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. 我不确定此转换的目的是什么,但结果是XML可能很难被下游应用程序使用。

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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