xsl-list
[Top] [All Lists]

Re: [xsl] Excluding an element with specific content from an <xsl:sort> call

2010-01-31 02:00:08
At 2010-01-31 03:07 +0100, Hermann Stamm-Wilbrandt wrote:
Under the assumption that 'A' only appears as length-1 string in Prefix
the following diff makes that stylesheet work on XSLT 1.0 processors:

$ diff mark.xsl mark1.xsl
10c10
<        <xsl:sort select="if( Prefix!='A' ) then Prefix else ''"/>
---
>        <xsl:sort select="translate(Prefix,'A','')"/>
$

When I find I have to do conditional expressions in XPath 1 I try to find a way of expressing the logic in a predicate, which in this case would not restrict the solution to only singleton-character strings:

   <xsl:sort select="Prefix[.!='A']"/>

... as illustrated below.

Note this can even work in Path 1 when you need to express a choice of some kind between nodes. What if the original requirement were to use the Prefix1 child in one condition and the Prefix2 child in another condition? In XPath 2 this would be simply:

   <xsl:sort select="if( $condition ) then Prefix1 else Prefix2"/>

... but without a conditional in XPath 1, I would approach this something like:

   <xsl:sort select="Prefix1[$condition] | Prefix2[not($condition)]"/>

Soon after the release of XSLT/XPath in 1999 it was necessary to come up with such schemes for conditional XPath expressions to meet real-world requirements from my customers. Modify the original poster's requirement that Prefix2 is optional but has precedence over Prefix1 when both are present, knowing that Prefix2 is after Prefix1 in document order:

     <xsl:sort select="(Prefix1 | Prefix2)[last()]"/>

... or more generally regardless of document order:

     <xsl:sort select="Prefix1[not(../Prefix2)] | Prefix2"/>

Just remember when dealing with nodes in XPath 1 to express the union of the two mutually-exclusive node sets expressing the binary results of the condition. Only one of the union operands will be non-empty.

I hope this is considered helpful.

. . . . . . . . . . . Ken

t:\ftemp>type mark.xml
<tests>
 <record>
  <order>1</order>
  <Prefix>D</Prefix>
 </record>
 <record>
  <order>2</order>
  <Prefix>A</Prefix>
 </record>
 <record>
  <order>3</order>
  <Prefix>L</Prefix>
 </record>
 <record>
  <order>4</order>
  <Prefix>A</Prefix>
 </record>
 <record>
  <order>5</order>
 </record>
 <record>
  <order>6</order>
  <Prefix>A</Prefix>
 </record>
 <record>
  <order>7</order>
 </record>
 <record>
  <order>8</order>
  <Prefix>L</Prefix>
 </record>
 <record>
  <order>9</order>
  <Prefix>D</Prefix>
 </record>
</tests>

t:\ftemp>call xslt mark.xml mark.xsl
<?xml version="1.0" encoding="utf-8"?><tests><record>
  <order>2</order>
  <Prefix>A</Prefix>
 </record><record>
  <order>4</order>
  <Prefix>A</Prefix>
 </record><record>
  <order>5</order>
 </record><record>
  <order>6</order>
  <Prefix>A</Prefix>
 </record><record>
  <order>7</order>
 </record><record>
  <order>1</order>
  <Prefix>D</Prefix>
 </record><record>
  <order>9</order>
  <Prefix>D</Prefix>
 </record><record>
  <order>3</order>
  <Prefix>L</Prefix>
 </record><record>
  <order>8</order>
  <Prefix>L</Prefix>
 </record></tests>
t:\ftemp>type mark.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:template match="tests">
  <xsl:copy>
    <xsl:for-each select="record">
      <xsl:sort select="Prefix[.!='A']"/>
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

t:\ftemp>rem Done!



--
XSLT/XQuery/XPath training after http://XMLPrague.cz 2010-03-15/19
XSLT/XQuery/XPath training:   San Carlos, California 2010-04-26/30
Vote for your XML training:   http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--