Re: [xsl] Looping

Subject: Re: [xsl] Looping
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 11 Apr 2012 16:13:34 -0400
At 2012-04-11 16:01 -0400, Nathan Tallman wrote:
I'm a fairly new XSL user and am still figuring things out. Right now
I'm having trouble looping through repeated elements.

You are not taking context into account.


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>

In the above you are going to the top of the document for your <xsl:value-of> rather than addressing the attribute from the context of the <language> element.


So you want:

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

... because at the point of the <xsl:value-of> your context node is the <language> element addressed in your <xsl:for-each>. My example is using a relative XPath address from the context node.

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.

Yes, because you are addressing all language codes with your absolute address in your <xsl:value-of>. The XSLT 1.0 processor is then giving you the value of the first one addressed.


I hope this helps.

. . . . . . . . . . Ken

p.s. in the five hours of video XSLT instruction I have posted for free at http://www.CraneSoftwrights.com/links/udemy-ptux-online.htm you can follow me working through some simple examples in Module 2 Lesson 4 (Lecture 6) that might help. You do not need to create an account to view the free content. Simply close the login dialogue box that is presented and click on that lesson's icon.

--
Public XSLT, XSL-FO, UBL and code list classes in Europe -- May 2012
Contact us for world-wide XML consulting and instructor-led training
Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm
Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/s/
G. Ken Holman                   mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Google+ profile: https://plus.google.com/116832879756988317389/about
Legal business disclaimers:    http://www.CraneSoftwrights.com/legal

Current Thread