Reputation: 5
I've been banging my head against the wall with this one. I have a series of XML like so:
<INTELLCONT id="33954082817" dmd:lastModified="2011-04-05T13:38:05" dmd:startDate="2010-12-30" dmd:endDate="2010-12-30">
<CONTYPE>Journal Article</CONTYPE>
<CONTYPEOTHER/>
<CLASSIFICATION>Learning and Pedagogical Research</CLASSIFICATION>
<STATUS>Not Accepted</STATUS>
<TITLE>The Use of Alternative Quiz Formats to Enhance Students’ Experiences in the Introductory Accounting Course</TITLE>
</INTELLCONT>
<INTELLCONT id="11473068032" dmd:lastModified="2012-08-30T14:12:05" dmd:startDate="2009-03-17" dmd:endDate="2010-11-30">
<CONTYPE>Journal Article</CONTYPE>
<CONTYPEOTHER/>
<CLASSIFICATION>Learning and Pedagogical Research</CLASSIFICATION>
<STATUS>Published</STATUS>
<TITLE>"Using Debate to Enhance Critical Thinking in the Accounting Classroom: Two Examples of Debates on the Sarbanes-Oxley Act and Tax Policy Issues</TITLE>
(I've removed some of the other tags for brevity). For anyone xml file, there might be 10-20 of these <INTELLCONT>
tags. I need to surface the values of the first five of some fields within the <INTELLCONT>
, but only the entries where the <PUBLISH>
tag is set to "Published". Here's the xsl so far:
<xsl:choose>
<xsl:when test="dm:Data/dm:Record/dm:INTELLCONT/dm:STATUS = 'Published'">
<xsl:for-each select="dm:Data/dm:Record/dm:INTELLCONT[1]">
<xsl:if test="dm:STATUS = 'Published'">
<p><xsl:value-of select="dm:TITLE" />,
<xsl:choose>
<xsl:when test="dm:JOURNAL/dm:JOURNAL_NAME !=''">
<i><xsl:value-of select="dm:JOURNAL/dm:JOURNAL_NAME"/></i>,
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="dm:DTM_PUB !=''">
<xsl:value-of select="dm:DTM_PUB"/>,
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="dm:DTY_PUB"/></p>
</xsl:if>
</xsl:for-each>
</xsl:when>
</xsl:choose>
This will surface the first entry, but only if <STATUS
> is set to "Published". This is fine, but like in the xml above, since the <STATUS>
is not "Published", nothing shows. This is also fine, but if I put this code in, and enumerate this line <xsl:for-each select="dm:Data/dm:Record/dm:INTELLCONT[1]">
out to <xsl:for-each select="dm:Data/dm:Record/dm:INTELLCONT[5]">
then I'll get all of the entries where <STATUS>
is published, but if there are fewer than 5 that are published, then I won't get the list of 5 entries that I need.
I know there has to be a better way to do this, but I haven't figured it out yet. Any help would be great!!
Upvotes: 0
Views: 3065
Reputation: 163675
I don't fully understand your explanation of the requirements, but you seem to be going about it in quite the wrong way. You need to learn about template rules, which are the natural way of writing code in XSLT!
If you want to display the first five INTELLCONT elements with a STATUS of Published, use
<xsl:apply-templates select="dm:INTELLICONT[dm:STATUS='Published'][position() <= 5]"/>
Then write a template rule to display them:
<xsl:template match=:dm:INTELLICONT">
<p><xsl:apply-templates/></p>
</xsl:template>
Then write template rules for the individual fields:
<xsl:template match="dm:JOURNAL[dm:JOURNAL_NAME != '']">
<i><xsl:value-of select="dm:JOURNAL_NAME"/></i>
</xsl:template>
When you see XSLT code written by experts, you'll find there are very few for-each, choose, or if instructions.
Upvotes: 4