Here's one solution, which is simple enough and doesn't need the
xx:node-set() extension function.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kWeight" match="@weight" use="../@id"/>
<xsl:template match="/">
<xsl:for-each select="/*/items/item">
<xsl:sort
select="concat('0',key('kWeight', @category) )
+ 1 * (1 - count(key('kWeight',
@category
)
)
)"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
When applied on your source.xml (corrected to be well-formed):
<root>
<items>
<item category="1" data="ggg">
<date year="1995" month="4" day="13"/>
</item>
<item category="2" data="hhh">
<date year="1984" month="7" day="22"/>
</item>
<item category="3" data="www">
<date year="1991" month="3" day="12"/>
</item>
<item category="3" data="rrr">
<date year="1999" month="6" day="19"/>
</item>
<item category="4" data="xxx">
<date year="1982" month="2" day="17"/>
</item>
<item category="5" data="kkk">
<date year="2000" month="12" day="11"/>
</item>
</items>
<categories>
<category id="1" weight="0"/>
<category id="3" weight="2"/>
<category id="4" weight="1"/>
</categories>
</root>
produces this result:
<item category="1" data="ggg">
<date year="1995" month="4" day="13" />
</item>
<item category="2" data="hhh">
<date year="1984" month="7" day="22" />
</item>
<item category="4" data="xxx">
<date year="1982" month="2" day="17" />
</item>
<item category="5" data="kkk">
<date year="2000" month="12" day="11" />
</item>
<item category="3" data="www">
<date year="1991" month="3" day="12" />
</item>
<item category="3" data="rrr">
<date year="1999" month="6" day="19" />
</item>
So, the items are correctly sorted according to the weight of the
corresponding category, or if the category is missing, then to the
default weight (1).
I haven't coded the additional sort by date, leaving this as an
exercise.
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Taras Tielkes" <taras(_at_)info(_dot_)nl> wrote in message
news:DEA593548993924AAEA173FE34217C170F0E06(_at_)ls4(_dot_)buro(_dot_)info(_dot_)nl(_dot_)(_dot_)(_dot_)
Hi,
My source xml has the following format:
<root>
<items>
<item category="1" data="ggg">
<date year="1995" month="4" day="13"/>
</item>
<item category="2" data="hhh">
<date year="1984" month="7" day="22"/>
</item>
<item category="3" data="www">
<date year="1991" month="3" day="12"/>
</item>
<item category="3" data="rrr">
<date year="1999" month="6" day="19"/>
</item>
<item category="4" data="xxx">
<date year="1982" month="2" day="17"/>
</item>
<item category="5" data="kkk">
<date year="2000" month="12" day="11"/>
</item>
</items>
<categories>
<category id="1" weight="0">
<category id="3" weight="2">
<category id="4" weight="1">
</categories>
</root>
1) The source xml contains a list of items.
Each item carries a 'data' attribute, which is the actual content
of the
item.
Apart from that, each item contains:
a) a 'catagory' attribute, identifying the catagory that the item
belogs
to.
b) a 'date' child element, representing the date of the item
Each item has an implied weight, implied by the category that it
references. (but see [2] and [3])
2) The source xml also contains a list of categories.
Each category contains a 'weight' attribute, which carries the
'importance' of the category.
Weight is from 0 (least important) to 2 (most important), in other
words
[0,2].
3) Some of the categories referred to by the item elements are not
present
in the source xml.
A default weight of 1 should be assumed in that case.
In the example xml, the categories (2,5) are absent.
I would like to sort the item elements using the following criteria:
1) first, by (implied) weight
2) second, by date
It seems to me that the problem would be easy if all referenced
categories
were present in the source xml.
In that case, I could use xsl:key to retreive the matching weight for
each
item.
However, that is not the case. It seems that what I want is to grab a
default weight of 1 wherever the references category is not present
in the
source xml.
Using SQL, for instance, I could use an outer join, specifying a
default
value.
Is there any solution for this problem in XSLT?
Thanks in advance for any feedback,
tt
__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list