Domanda

Given the following xml document...

   <ws>
       <series year="2005" mvp="Jermaine Dye">
          <team name="Chicago White Sox" wins="4" />
          <team name="Houston Astros" wins="0" />
       </series>
       <series year="2004" mvp="Manny Ramirez">
          <team name="Boston Red Sox" wins="4" />
          <team name="St. Louis Cardinals" wins="0" />
       </series>
    </ws>

I have created a key to get the name attribute of the first team in each series, and I am trying to loop through and list out each name for each series as follows; I am currently not returning any results and am not sure what is wrong with my value-of reference?...

<xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series">
             <xsl:value-of select="key('winners', @name)" />
        </xsl:for-each>
    </xsl:template>

Expected output would be...

Chicago White Sox (the first team from series 1)
Boston Red Sox (the first team from series 2)

The xml data I have provided only includes 2 series elements when in actuality there are hundred's. The key is used to speed up the transformation process and works along with other keys to generate my result document.

È stato utile?

Soluzione

I am trying to list out the name of the first team in each series

Using a key is an unnecessary complication for such a simple task. Try simply:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
    </xsl:for-each>
</xsl:template>

Of course, you will want to add some kind of wrapper or separator to this, otherwise you'll just get a jumble of all names - say (assuming the output method is text):

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

EDIT:

To do this (artificially) using a key, you must ask yourself what is connecting a team to its series (other than being a child thereof). The answer here is 'nothing'. However, a team has access to its parent series data. Therefore we could identify a team by some attribute of its parent series, such as the year or the MVP. The MVP might not be unique to the series, so let's make the key:

<xsl:key name="team-by-year" match="team" use="parent::series/@year" />

This says: if you tell me the year, I'll tell you the teams that played in the series of that year. So from here, it's simply a matter of calling a key with the current series' year:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="key('team-by-year', @year)[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

Altri suggerimenti

If you use this

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

    <xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series/*">
            <xsl:value-of select="key('winners', @name)/@name" />
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top