Re: [xsl] matching attribute values that are in range

Subject: Re: [xsl] matching attribute values that are in range
From: "andrew welch" <andrew.j.welch@xxxxxxxxx>
Date: Wed, 19 Jul 2006 12:12:46 +0100
On 7/19/06, Jeff Sese <jsese@xxxxxxxxxxxx> wrote:
hi!

i'm trying to match an element that may have an attribute value that is
in a range format (1-5), and is located on a separate xml document; how
can i get my xpath to match?

xml source:

<entry id='1' type='t' n='1'>some text</entry>
<entry id='1' type='t' n='2'>some text</entry>
<entry id='1' type='t' n='3'>some text</entry>
<entry id='1' type='t' n='4'>some text</entry>
<entry id='1' type='t' n='5'>some text</entry>
xml source 2:

<entry id='1' type='t' n='1-5'>some text2</entry>

needed output:

<entry id='1' type='t' n='1'>some text some text2</entry>
<entry id='1' type='t' n='2'>some text some text2</entry>
<entry id='1' type='t' n='3'>some text some text2</entry>
<entry id='1' type='t' n='4'>some text some text2</entry>
<entry id='1' type='t' n='5'>some text some text2</entry>

Access the 2nd document using the document() function:


<xsl:variable name="doc2" select="document('doc2.xml')/>

Get the range values using substring (or tokenize() in XSLT 2.0) and
the text value from doc2:

<xsl:variable name="minRange" select="substring-before($doc2/entry/@n, '-')"/>
<xsl:variable name="maxRange" select="substring-after($doc2/entry/@n, '-')"/>
<xsl:variable name="doc2Text" select="$doc2/entry"/>

(you will have to adjust the paths to suit your real life data)

Then select the <entry> elements you are interested in:

<xsl:apply-templates select="entry[@n >= $minRange][@n &lt;= $maxRange]"/>

Write the template to create the output you're after:

<xsl:template match="entry">
 <xsl:copy>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>
   <xsl:value-of select="$doc2Text"/>
 </xsl:copy>
</xsl:template>

That template might look a bit strange, but will scale better than the
simpler alternative:

<xsl:template match="entry">
 <entry id='{@id}' type='{@type}' n='{@n}'>
   <xsl:value-of select="."/>
   <xsl:value-of select="$doc2Text"/>
 </entry>
</xsl:template>

This one will do what you need for your given input, but the template
above is the better solution if you expect the name or number of
attribute to change, or if the <entry> element will ever contain
anything more than just text.

cheers
andrew

Current Thread