473,721 Members | 1,708 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

XSLT sort based on attributes

given the following DOM snippet;

<root>
<sub1 foo="4">testing </sub1>
<sub1 foo="0">hello</sub1>
<sub1 foo="0">world</sub1>
<sub1>hello again</sub1>
</root>

I need to transform with XSL to something like;

start foo = 0
hello
world
end foo = 0

start foo = 4
testing
end foo = 4

hello again
The (hopefully clear) constraints are that the attribute foo is
optional and that it may be any whole number if present, though may or
may not be sequential.

Sorting the nodeset based on the value of foo I can manage (!), but I
can't figure out how to output the boundary markers shown. Can anyone
help??

Many TIA!
Jul 20 '05 #1
8 3401
Darren Davison wrote:
given the following DOM snippet;

<root>
<sub1 foo="4">testing </sub1>
<sub1 foo="0">hello</sub1>
<sub1 foo="0">world</sub1>
<sub1>hello again</sub1>
</root>

I need to transform with XSL to something like;

start foo = 0
hello
world
end foo = 0

start foo = 4
testing
end foo = 4

hello again
The (hopefully clear) constraints are that the attribute foo is
optional and that it may be any whole number if present, though may or
may not be sequential.

Sorting the nodeset based on the value of foo I can manage (!), but I
can't figure out how to output the boundary markers shown. Can anyone
help??
I think so. Try this:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http ://www.w3.org/2001/XMLSchema"

<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="root/sub1[@foo]">
<xsl:sort select="@foo" order="ascendin g"/>
</xsl:apply-templates>
<xsl:apply-templates select="root/sub1[not(@foo)]">
<xsl:sort select="@foo" order="ascendin g"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sub1">
<xsl:if test="not(@foo= preceding::node ()/@foo)">
<xsl:text>
</xsl:text>
<xsl:if test="@foo">
<xsl:text>sta rt foo = </xsl:text>
<xsl:value-of select="@foo"/>
</xsl:if>
</xsl:if>
<xsl:text>
</xsl:text>
<xsl:value-of select="."/>
<xsl:if test="not(@foo= following::node ()/@foo)">
<xsl:text>
</xsl:text>
<xsl:if test="@foo">
<xsl:text>end foo = </xsl:text>
<xsl:value-of select="@foo"/>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

When I run that on the data you've posted, I get this output:
start foo = 0
hello
world
end foo = 0

start foo = 4
testing
end foo = 4
hello again

That's pretty close to what you wanted, if I understood you correctly.
If not, you can probably see how to modify it. If you don't actually
need the non-foo nodes at the end (and could accept them at beginning of
the output) then you can just elimate the second apply-templates in the
root template and change the select clause of the first one to be just
root/sub1.

Ed

Jul 20 '05 #2

This is a standard grouping guestion, see
http://www.jenitennison.com/xslt/grouping

something like

<xsl:key name="x" match="sub1" use="foo"/>

<xsl:template match="root">
<xsl:for-each select="sub1[generate-id()=generate-id(key('x',@foo ))]">
<xsl:sort select="@foo" data-type="number"/>
<xsl:if test="@foo">sta rt foo = <xsl:value-of select="@foo"/></xsl:if>
<xsl:for-each select="key('x' ,@foo)">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:if test="@foo">end foo = <xsl:value-of select="@foo"/></xsl:if>
</xsl:for-each>
</xsl:template>

David
Jul 20 '05 #3
David Carlisle wrote:
This is a standard grouping guestion, see
http://www.jenitennison.com/xslt/grouping
looks like a pretty useful site - bookmarked!
something like

<xsl:key name="x" match="sub1" use="foo"/>

<xsl:template match="root">
<xsl:for-each select="sub1[generate-id()=generate-id(key('x',@foo ))]">
<xsl:sort select="@foo" data-type="number"/>
<xsl:if test="@foo">sta rt foo = <xsl:value-of select="@foo"/></xsl:if>
<xsl:for-each select="key('x' ,@foo)">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:if test="@foo">end foo = <xsl:value-of select="@foo"/></xsl:if>
</xsl:for-each>
</xsl:template>


Thanks very much for your help David

:)
--
darren@ public key
davisononline.o rg #DD356B0D

Jul 20 '05 #4
Ed Beroset wrote:
I think so. Try this:
- snip -
That's pretty close to what you wanted, if I understood you correctly.
If not, you can probably see how to modify it. If you don't actually
need the non-foo nodes at the end (and could accept them at beginning of
the output) then you can just elimate the second apply-templates in the
root template and change the select clause of the first one to be just
root/sub1.


Many thanks for your help Ed.

--
darren@******** ********public* key
davisononline.o rg******#DD356B 0D
Jul 20 '05 #5
Darren Davison schrieb:
David Carlisle wrote:

This is a standard grouping guestion, see
http://www.jenitennison.com/xslt/grouping

...


I was thinking about the Problem with the optional @foo which is not
handled in Davids solution.

I tried to solve this but ended up in a bit messy code :-(

Are there more elegant solutions?

Jo

<?xml version="1.0" encoding="UTF-8"?>
<xsl:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:key name="fooKey" match="sub1" use="@foo" />
<xsl:output omit-xml-declaration="ye s" method="text" />
<xsl:preserve-space elements="/" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>

<xsl:template match="root">
<xsl:for-each select="sub1[generate-id() =
generate-id(key('fooKey' ,@foo)[1])] | sub1[not(@foo)]">
<xsl:variable name="fooParm" select="@foo" />
start foo=<xsl:value-of select="$fooPar m" /><xsl:text> </xsl:text>
<xsl:for-each select="../sub1[@foo = $fooParm or (not(@foo) and
not($fooParm))]">
<xsl:value-of select="." /><xsl:text> </xsl:text>
</xsl:for-each>
end foo=<xsl:value-of select="$fooPar m" /><xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>

<xsl:template match="sub1[@foo]">
<xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet>

Jul 20 '05 #6

I was thinking about the Problem with the optional @foo which is not
handled in Davids solution.

my code handles an omitted foo the same as foo="" Given that foo had
numeric values I assumed that "" would not be a legal value and so
no distinction between these cases was necessary.

David
Jul 20 '05 #7

I wrote
I was thinking about the Problem with the optional @foo which is not
handled in Davids solution.

my code handles an omitted foo the same as foo="" Given that foo had
numeric values I assumed that "" would not be a legal value and so
no distinction between these cases was necessary.


although in fairness I should say there were some typos so actually my
code wouldn't run at all, also the original poster wanted "" to sort
high whereas by default it sorts low. The code below fixes the typos and
negates the sort key so "" (NaN) sorts high.
<?xml version="1.0" encoding="utf-8"?>
<xsl:styleshe et xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:key name="x" match="sub1" use="string(@fo o)"/>

<xsl:template match="root">
<xsl:for-each select="sub1[generate-id()=generate-id(key('x',stri ng(@foo)))]">
<xsl:sort select="-@foo" data-type="number" order="descendi ng"/>
<xsl:if test="@foo"> st art foo = <xsl:value-of select="@foo"/></xsl:if>
<xsl:for-each select="key('x' ,string(@foo))" >
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:if test="@foo"> en d foo = <xsl:value-of select="@foo"/></xsl:if>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
$ saxon8 sort.xml sort.xsl
Warning: Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<?xml version="1.0" encoding="UTF-8"?>
start foo = 0
hello

world

end foo = 0
start foo = 4
testing

end foo = 4
hello again
Jul 20 '05 #8
David Carlisle schrieb:
I wrote

I was thinking about the Problem with the optional @foo which is not
handled in Davids solution.

my code handles an omitted foo the same as foo="" Given that foo had
numeric values I assumed that "" would not be a legal value and so
no distinction between these cases was necessary.

...


You 're right!

I created a problem, where no problem exists.

Jo

Jul 20 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3381
by: Igor | last post by:
Is there any way to resort and xml document using xslt based on element position. For example if I have xml like this: <root> <element> 1st thing </element> <element> 2nd thing </element> <element> 3rd thing </element> </root> would it be possible using xslt only to reverse it into:
9
2896
by: Iain | last post by:
I want to create an XML configuration file which might look like <REGION Name="Europe" WingDing="Blue"> <COUNTRY Name="UK" WingDing="white"> <TOWN Name="London" WingDing="Orange" /> </COUNTRY> </REGION> <REGION Name="NorthAmerica" WingDing="Yellow"> <COUNTRY Name="Canada"> <TOWN Name="Quebec" WingDing="Brown" />
1
2344
by: David | last post by:
I would like to be able to re-sort data in an HTML table on the without returning to the server. It seems like an XSLT should be able to accomplish this, but I can't find enough information... I have am XML file generated on the server that looks something like this: <?xml version="1.0" encoding="utf-8" ?> <?xml-stylesheet type="text/xsl" href="search.xsl"?> <AlbumSearch version="3.0" time="02Apr04 10:54:31 EST"> <SearchResults...
2
1841
by: Jon Martin Solaas | last post by:
Hi, I have a general document somewhat like this: -------------------------------------- <root> <level1> <level2> <interestingstuff number="2"/> <interestingstuff number="3"/> <interestingstuff number="1"/>
3
1760
by: Alex | last post by:
I stumbled upon this while developing a custom XPathNavigator. It appears that copy action for attributes is broken in the .net framework XSLT processor. The intent was to just copy the entities and attributes from the source XML into the output using simple "identity" like XSLT: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/>
3
2196
by: Teksure | last post by:
Hi group, searching in the Internet I found two products for XML which incorporate a very robust debugger for XSL/XSLT, I would like you to see these products and then, give me your opinion about the development environment or recommend me some other that you know. XML IDE's - http://xslt-process.sourceforge.net - http://www.mentattech.com/themes/mentat/alchemist/index.html Regards,
7
2866
by: Harolds | last post by:
The code below worked in VS 2003 & dotnet framework 1.1 but now in VS 2005 the pmID is evaluated to "" instead of what the value is set to: .... xmlItems.Document = pmXML // Add the pmID parameter to the XSLT stylesheet XsltArgumentList xsltArgList = new XsltArgumentList(); xsltArgList.AddParam("pmID", "", pmID); xmlItems.TransformArgumentList = xsltArgList;
4
8991
by: David S. Alexander | last post by:
How can I do simple subtraction in an XSLT. I want to read a few attribute values from an XML document, calculate their difference, and transform that value to an attribute in the XML output document. My original XML is, <Dates> <Birth Year="1966" />
3
2007
by: thomas.porschberg | last post by:
Hi, I want to read records from a database and export it in an arbitrary format. My idea was to feed a class with a String array fetched from the database and let this class fire SAX events as processor input. The basic class hierarchy is:
0
8844
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9370
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9067
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8009
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6672
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5986
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4487
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4755
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2578
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.