views:

56

answers:

2

I am creating an XSLT and i want to select a particular node, only if one of its child element's value is between a range. The range is to be specified using parameters in the xsl file.

The XML file is like

<root>
 <org>
  <name>foo</name>
  <chief>100</chief>
 </org>
 <org parent="foo">
  <name>foo2</name>
  <chief>106</chief>
 </org>
</root>

The XSLT so far is

<xsl:param name="fromRange">99</xsl:param>
<xsl:param name="toRange">105</xsl:param>

<xsl:template match="/">
    <xsl:element name="orgo">
        <xsl:apply-templates select="//org[not(@parent)]"/>
    </xsl:element>
</xsl:template>

I want to restrict the org node from being processed whose < chief > node's value is not in range

A: 
//org[chief &lt; $fromRange and not(@parent)]
    |//org[chief > $toRange and not(@parent)]

This expression will exclude all nodes that are in the range specified by fromRange and toRange.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="xml" indent="yes"/>

  <xsl:param name="fromRange">99</xsl:param>
  <xsl:param name="toRange">105</xsl:param>

  <xsl:template match="/">
    <xsl:element name="orgo">
      <xsl:apply-templates select="//org[chief &lt; $fromRange and not(@parent)]|//org[chief > $toRange and not(@parent)]"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>
0xA3
I think OP wants in range nodes.
Alejandro
+1  A: 

I want to select a particular node, only if one of its child element's value is between a range. The range is to be specified using parameters in the xsl file.

I also want the restriction that the node should not have a parent attribute along with the range

Use this expression as the value of the select attribute of <xsl:apply-templates>:

org[not(@parent) and chief >= $fromRange and not(chief > $toRange)]

In XSLT 2.0 it is legal to have variables/parameters in the match pattern.

Therefore, one could write:

<xsl:template match=
  "org[@parent or not(chief >= $fromRange ) or chief > $toRange]"/>

thus effectively excluding all such org elements from processing.

Then the template matching the document node is simply:

<xsl:template match="/">            
    <orgo>            
        <xsl:apply-templates/>            
    </orgo>            
</xsl:template>

This is better than the XSLT 1.0 solution, because it is more "push-style".

Dimitre Novatchev
+1 for variable/parameter ussing in patterns diferences.
Alejandro