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

Subject: Re: [xsl] Excluding an element with specific content from an <xsl:sort> call
From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx>
Date: Sat, 30 Jan 2010 23:05:41 +0100
Hi Mark,

I think if you only want to sort elements where no two items share the same 'hash' (i.e., concatenated property values), Ken's solution is perfect. This is because each item will be in a group of its own, and these single-element groups will be properly sorted according to the given criteria.

But if you really want to *group* equivalent items as in the following ficticious output example, I think you'll have to consider nested for-each-groups.

<catalog name="cat1">
  <prefixGroup prefix="NilOrA">
    <item catalogNumber="34">
      ...
    </item>
    <item catalogNumber="36">
      ...
    </item>
  </prefixGroup>
  <prefixGroup prefix="B">
    <item catalogNumber="24">
      ...
    </item>
  </prefixGroup>
</catalog>
...

Gerrit

On 30.01.2010 22:51, Mark Wilson wrote:
Hi Gerrit,
A very good comment, but in this instance the for-each-group coding does
what I need it to. However, I will make a note of your advise in case
circumstances change.
Mark

--------------------------------------------------
From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx>
Sent: Saturday, January 30, 2010 1:42 PM
To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: [xsl] Excluding an element with specific content from an
<xsl:sort> call

Another idea why Mark wasn't satisfied with the suggested solution:

Maybe he intended to have a nested for-each-group instead of
concatenated group-by arguments. If he selects the concatenated
strings as group-by keys, he will have strings like

'fooAbar' 'fooCbar' 'foobar'

But then 'fooAbar' isn't equivalent with 'foobar' (with an empty
prefix instead of 'A' between the other strings 'foo' and 'bar'), as
he expected. The items with prefix 'A' will be in another group than
the items without prefix.

Therefore he should probably group by CatalogName first, then inside
each group by Prefix (thereby treating 'A' and '' as equivalent as you
suggested), then by the other tie-breakers.

Gerrit



On 30.01.2010 22:23, G. Ken Holman wrote:
At 2010-01-30 13:05 -0800, Mark Wilson wrote:
Thanks Ken,
But it did not work.

My bad ... in my haste I neglected to think of the behaviour triggered in the "if" statement when the Prefix element is absent. When an operand of the comparison operator is the empty set, the comparison returns false.

It worked for me when I turned the expression inside out:

<xsl:sort select="if( Prefix!='A' ) then Prefix else ''"/>

Now the same '' value is used for sorting if the prefix is 'A' (the test
calculates as false) or the prefix is absent (the test defaults as
false).

I hope the illustration below helps. Note how document order is
maintained for all records that have no prefix or the prefix is 'A',
thus proving they are being sorted with the same value.

. . . . . . . . . . . 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 xslt2 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="2.0">

<xsl:output indent="yes"/>

<xsl:template match="tests">
<xsl:copy>
<xsl:for-each select="record">
<xsl:sort select="if( Prefix!='A' ) then Prefix else ''"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>rem Done!



--
UBL and Code List training: Copenhagen, Denmark 2010-02-08/10
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@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers: http://www.CraneSoftwrights.com/legal


-- Gerrit Imsieke Geschdftsf|hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

Geschdftsf|hrer: Gerrit Imsieke, Svea Jelonek,
Thomas Schmidt, Dr. Reinhard Vvckler


-- Gerrit Imsieke Geschdftsf|hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

Geschdftsf|hrer: Gerrit Imsieke, Svea Jelonek,
Thomas Schmidt, Dr. Reinhard Vvckler

Current Thread