RE: [xsl] Looping

Subject: RE: [xsl] Looping
From: Michele R Combs <mrrothen@xxxxxxx>
Date: Wed, 11 Apr 2012 20:19:29 +0000
If you just use plain old "for-each" with no index, it will loop over all of
them; when you output, just grab the node you're in rather than using the full
root address.  Like so:

<xsl:if test="/ead/archdesc/did/langmaterial">
    <xsl:for-each select="/ead/archdesc/did/langmaterial/language">
        <marc:datafield tag="041" ind1=" " ind2=" ">
            <marc:subfield code="a">
                <xsl:value-of select="normalize-space(@langcode)"/>
            </marc:subfield>
        </marc:datafield>
    </xsl:for-each>

Michele

-----Original Message-----
From: Nathan Tallman [mailto:ntallman@xxxxxxxxx]
Sent: Wednesday, April 11, 2012 4:01 PM
To: xsl-list
Subject: [xsl] Looping

Hi XSL list,

I'm a fairly new XSL user and am still figuring things out. Right now I'm
having trouble looping through repeated elements.

Here's my source XML snippet:

<ead>
...
    <archdesc>
    ...
        <did>
        ...
            <langmaterial encodinganalog="546">Collection material in
                <language encodinganalog="041$a"
langcode="eng">English</language>,
                <language encodinganalog="041$a"
langcode="yid">Yiddish</language>, and
                <language encodinganalog="041$a"
langcode="rus">Russian</language>.
            </langmaterial>

Here's my XSL snippet:

<xsl:if test="/ead/archdesc/did/langmaterial">
    <xsl:for-each select="/ead/archdesc/did/langmaterial/language[1]">
        <marc:datafield tag="041" ind1=" " ind2=" ">
            <marc:subfield code="a">
                <xsl:value-of
select="normalize-space(/ead/archdesc/did/langmaterial/language[1]/@langcode)
"
/>
            </marc:subfield>
        </marc:datafield>
    </xsl:for-each>

    <xsl:for-each select="/ead/archdesc/did/langmaterial/language[2]">
        <marc:datafield tag="041" ind1=" " ind2=" ">
            <marc:subfield code="a">
                <xsl:value-of
select="normalize-space(/ead/archdesc/did/langmaterial/language[2]/@langcode)
"
/>
            </marc:subfield>
        </marc:datafield>
    </xsl:for-each>

    <xsl:for-each select="/ead/archdesc/did/langmaterial/language[3]">
        <marc:datafield tag="041" ind1=" " ind2=" ">
            <marc:subfield code="a">
                <xsl:value-of
select="normalize-space(/ead/archdesc/did/langmaterial/language[3]/@langcode)
"
/>
            </marc:subfield>
        </marc:datafield>
    </xsl:for-each>
</xsl:if>

Right now, this achieves what I want. Each langcode is represented by an
individual MARC 041 field. But, as you can see, I have hard coded each node
sequentially. In my XSL, I repeat this ten times, in anticipation of more
langcodes. Is there an easy way to code the output I want, and then have this
loop until it has covered each instance of <language>?

I've tried this:
			   <xsl:if test="/ead/archdesc/did/langmaterial">
			      <xsl:for-each select="/ead/archdesc/did/langmaterial/language">
			         <marc:datafield tag="041" ind1=" " ind2=" ">
			            <marc:subfield code="a">
			               <xsl:value-of
select="normalize-space(/ead/archdesc/did/langmaterial/language/@langcode)"
/>
			            </marc:subfield>
			         </marc:datafield>
			      </xsl:for-each>
			   </xsl:if>
But it only repeats the first @langcode three times, instead of having three
distinct outputs.

Many thanks!

Current Thread