0

I see this similar question:

XSLT - How to select XML Attribute by Attribute?

But in my case my select statement is not using the / referred to in the answer. And in my case I am not using a literal text value but the value of the current element. See below.

OK, I have this external XML file:

<?xml version="1.0" encoding="utf-8"?>
<Lessons>
  <Study Number="1" Page="83"/>
  <Study Number="2" Page="86"/>
  <Study Number="3" Page="89"/>
  <Study Number="4" Page="93"/>
  <Study Number="5" Page="97"/>
  <Study Number="6" Page="101"/>
  <Study Number="7" Page="105"/>
  <Study Number="8" Page="107"/>
  <Study Number="9" Page="111"/>
  <Study Number="10" Page="115"/>
  <Study Number="11" Page="118"/>
  <Study Number="12" Page="121"/>
  <Study Number="13" Page="124"/>
  <Study Number="14" Page="128"/>
  <Study Number="15" Page="131"/>
  <Study Number="16" Page="135"/>
  <Study Number="17" Page="139"/>
  <Study Number="18" Page="143"/>
  <Study Number="19" Page="145"/>
  <Study Number="20" Page="147"/>
  <Study Number="21" Page="150"/>
  <Study Number="22" Page="153"/>
  <Study Number="23" Page="157"/>
  <Study Number="24" Page="160"/>
  <Study Number="25" Page="166"/>
  <Study Number="26" Page="170"/>
  <Study Number="27" Page="174"/>
  <Study Number="28" Page="179"/>
  <Study Number="29" Page="181"/>
  <Study Number="30" Page="186"/>
  <Study Number="31" Page="190"/>
  <Study Number="32" Page="194"/>
  <Study Number="33" Page="197"/>
  <Study Number="34" Page="202"/>
  <Study Number="35" Page="206"/>
  <Study Number="36" Page="209"/>
  <Study Number="37" Page="212"/>
  <Study Number="38" Page="215"/>
  <Study Number="39" Page="220"/>
  <Study Number="40" Page="223"/>
  <Study Number="41" Page="226"/>
  <Study Number="42" Page="230"/>
  <Study Number="43" Page="234"/>
  <Study Number="44" Page="236"/>
  <Study Number="45" Page="240"/>
  <Study Number="46" Page="244"/>
  <Study Number="47" Page="247"/>
  <Study Number="48" Page="251"/>
  <Study Number="49" Page="255"/>
  <Study Number="50" Page="258"/>
  <Study Number="51" Page="263"/>
  <Study Number="52" Page="265"/>
  <Study Number="53" Page="268"/>
</Lessons>

In my XSL script I am making a call like this:

<xsl:apply-templates select="BibleReadingM/@StudyPoint"/>

This is the template:

<xsl:template match="@StudyPoint">
    <xsl:variable name="StudyPageNumbers" select="document('StudyPointPageNumbers.xml')" />
    <xsl:text> (Page: </xsl:text>
    <xsl:value-of select="$StudyPageNumbers/Lessons/Study[@Number=.]/@Page" />
    <xsl:text>)</xsl:text>
</xsl:template>

I am trying to locate the right row from the linked in data file (@Number=<current_value>) and then to show the other attribute @Page on the same row. Or do I need to redesign my XML data file?

Aniket V
  • 3,183
  • 2
  • 15
  • 27
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164

1 Answers1

1

Change this:

<xsl:value-of select="$StudyPageNumbers/Lessons/Study[@Number=.]/@Page"/>

to:

<xsl:value-of select="$StudyPageNumbers/Lessons/Study[@Number=current()]/@Page"/>

See explanation here: https://www.w3.org/TR/xslt/#misc-func


Alternatively (and preferably, IMHO) use a key to perform the lookup:

<xsl:key name="studies" match="Study" use="@Number" />

<xsl:template match="@StudyPoint">
    <xsl:text> (Page: </xsl:text>
    <xsl:variable name="num" select="." />
    <!-- change context to use a key -->
    <xsl:for-each select="document('StudyPointPageNumbers.xml')">
        <xsl:value-of select="key('studies', $num)/@Page"/>
    </xsl:for-each>
    <xsl:text>)</xsl:text>
</xsl:template>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Thanks. In this case I don't want to loop all of them. Just the study point passed in. So I will stick with `current()` but thanks for introducing me to the concept of **keys**. – Andrew Truckle Aug 22 '17 at 12:25
  • 1
    @AndrewTruckle There is no loop here, only a change of context (in XSLT 1.0 keys do not work across documents). If your input has several study points, using a key will be more efficient because the XSLT processor will pre-index the lookup source. – michael.hor257k Aug 22 '17 at 12:31
  • I see. In my case I will only have a maximum of 4 to 8 entries each time my report is run. – Andrew Truckle Aug 22 '17 at 12:33
  • Out of interest, your xsl:key line. Where does that get put in the main xsl? At the top? – Andrew Truckle Aug 22 '17 at 17:53
  • 1
    At the top level, outside of any template. – michael.hor257k Aug 22 '17 at 18:26