1


私はこの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>

...この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>

...そしてこの出力を取得しています:

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





ただし、  出力が次のようになるように、すべてのAuthor  タグを1つの大きな  タグに連結しようとして  Authorいます。

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


for-each  何らかの方法でループ を使用する必要があり  ますか?

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/*(または/root)のテンプレートを追加して、一致Authorsから削除するだけです。contrib

<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 に答える