1


I am transforming this XML:

<root>
  <contrib contrib-type="author">
    <name>
      <last-name>Kottke</last-name>
      <first-name>Leo</first-name>
    </name>
  </contrib>

  <contrib contrib-type="author">
    <name>
      <last-name>McKee</last-name>
      <first-name>Andy</first-name>
    </name>
  </contrib>

  <contrib contrib-type="author">
    <name>
      <last-name>Hedges</last-name>
      <first-name>Michael</first-name>
    </name>
  </contrib>
</root>

...with this XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" method="xml"/>
    <xsl:strip-space elements="*"/>

    <!-- identity rule -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

        <!-- Authors -->
        <xsl:template match="contrib[@contrib-type='author']">
            <Authors>
              <xsl:if test="position() != last()">
                <xsl:value-of select = "concat(name/first-name, ' ', name/last-name, ', ')" />
              </xsl:if>

              <xsl:if test="position() = last()">
                <xsl:value-of select = "concat('and ', name/first-name, ' ', name/last-name, '.')" />
              </xsl:if>
            </Authors>
        </xsl:template>
</xsl:stylesheet>

...and am getting this output:

<root>
    <Authors>Leo Kottke, </Authors>
    <Authors>Andy McKee, </Authors>
    <Authors>and Michael Hedges.</Authors>
</root>





However, I am trying to concatenate all of the  Author  tags into one larger  Author  tag, so that the output would resemble this:

<root>
    <Authors>Leo Kottke, Andy McKee, and Michael Hedges.</Authors>
</root>


Do I need to use a  for-each  loop in some way?

4

2 回答 2

2

稍微简单一点的东西

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

    <xsl:template match="/root">
        <xsl:variable name="authors">
            <xsl:for-each select="contrib/name">
                <xsl:text>, </xsl:text>
                <xsl:value-of select="first-name"/>
                <xsl:text> </xsl:text>
                <xsl:value-of select="last-name"/>
            </xsl:for-each>
        </xsl:variable>

        <root>
            <authors><xsl:value-of select="substring($authors,3)"/></authors>
        </root>
    </xsl:template>

</xsl:stylesheet>
于 2012-08-08T19:22:28.330 回答
2

不需要xsl:for-each/*只需为(or /root)添加模板并Authorscontrib匹配中删除:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" method="xml"/>
    <xsl:strip-space elements="*"/>

    <!-- identity rule -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/root">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <Authors>
                <xsl:apply-templates select="contrib[@contrib-type='author']"/>
            </Authors>
        </xsl:copy>
    </xsl:template>

    <!-- Authors -->
    <xsl:template match="contrib[@contrib-type='author']">
        <xsl:if test="position() != last()">
            <xsl:value-of select = "concat(name/first-name, ' ', name/last-name, ', ')" />
        </xsl:if>

        <xsl:if test="position() = last()">
            <xsl:value-of select = "concat('and ', name/first-name, ' ', name/last-name, '.')" />
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
于 2012-08-08T19:14:07.377 回答