Maintain the order of the xml
-
Hi, I'm generating an xml dynamically and want to use xsl as a template (and therefore not generated dynamically). Here is an example of such xml: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="Template.xsl"?> <PeopleList order="1"> <item> <Name>John</Name> </item> <item> <Name>Doe</Name> </item> </PeopleList> <KidList order="2"> <item> <Name>Alex</Name> </item> <item> <Name>King</Name> </item> </KidList> Template.xsl looks like this: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <html> <body> <h2>My List</h2> <xsl:apply-templates select="KidList"/> <xsl:apply-templates select="PeopleList"/> </body> </html> </xsl:template> <xsl:template match="PeopleList"> <p> People List </p> </xsl:template> <xsl:template match="KidList"> <p> KidList </p> </xsl:template> </xsl:stylesheet> Result will be (the order was decided according xsl:apply-templates and not according the xml) :
My List
Kid List
People List
In the xml, PeopleList can come before KidList or after it and the order is matter - I want one xsl file that can display them in the right order. I added an "order" attribute but still don't know if it can help and how. Any suggestions?
-
Hi, I'm generating an xml dynamically and want to use xsl as a template (and therefore not generated dynamically). Here is an example of such xml: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="Template.xsl"?> <PeopleList order="1"> <item> <Name>John</Name> </item> <item> <Name>Doe</Name> </item> </PeopleList> <KidList order="2"> <item> <Name>Alex</Name> </item> <item> <Name>King</Name> </item> </KidList> Template.xsl looks like this: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <html> <body> <h2>My List</h2> <xsl:apply-templates select="KidList"/> <xsl:apply-templates select="PeopleList"/> </body> </html> </xsl:template> <xsl:template match="PeopleList"> <p> People List </p> </xsl:template> <xsl:template match="KidList"> <p> KidList </p> </xsl:template> </xsl:stylesheet> Result will be (the order was decided according xsl:apply-templates and not according the xml) :
My List
Kid List
People List
In the xml, PeopleList can come before KidList or after it and the order is matter - I want one xsl file that can display them in the right order. I added an "order" attribute but still don't know if it can help and how. Any suggestions?
Have you tried changing this:
<h2>My List</h2> <xsl:apply-templates select="KidList"/> <xsl:apply-templates select="PeopleList"/>
to this:<h2>My List</h2> <xsl:apply-templates select="PeopleList"/> <xsl:apply-templates select="KidList"/>
Mark's blog: developMENTALmadness.blogspot.com Funniest variable name: lLongDong - spotted in legacy code, was used to determine how long a beep should be. - Dave Bacher
-
Have you tried changing this:
<h2>My List</h2> <xsl:apply-templates select="KidList"/> <xsl:apply-templates select="PeopleList"/>
to this:<h2>My List</h2> <xsl:apply-templates select="PeopleList"/> <xsl:apply-templates select="KidList"/>
Mark's blog: developMENTALmadness.blogspot.com Funniest variable name: lLongDong - spotted in legacy code, was used to determine how long a beep should be. - Dave Bacher
Thanks for replying, but this is not the solution. The xml is built dynamically so sometimes KidList will be before PeopleList and sometimes not (I can't change the xsl so I need it to be generic). The solution is: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <html> <body> <xsl:apply-templates select="Lists"/> </body> </html> </xsl:template> <xsl:template match="Lists"> <h2>My List</h2> <xsl:for-each select="*"> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each> </xsl:template> <xsl:template match="PeopleList"> <p> People List </p> </xsl:template> <xsl:template match="KidList"> <p> KidList </p> </xsl:template> </xsl:stylesheet>
-
Thanks for replying, but this is not the solution. The xml is built dynamically so sometimes KidList will be before PeopleList and sometimes not (I can't change the xsl so I need it to be generic). The solution is: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <html> <body> <xsl:apply-templates select="Lists"/> </body> </html> </xsl:template> <xsl:template match="Lists"> <h2>My List</h2> <xsl:for-each select="*"> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each> </xsl:template> <xsl:template match="PeopleList"> <p> People List </p> </xsl:template> <xsl:template match="KidList"> <p> KidList </p> </xsl:template> </xsl:stylesheet>
If you can't control the order of KidList and PeopleList then the result your solution will always be the order of the xml document. If KidList is first in the Xml then it will be first in your output. If you need it to be more generic then you will need to do this:
<xsl:for-each select="*"> <xsl:sort select="@order" data-type="number" /> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each>
That is assuming you are still using the "order" attribute in your xml that was in your first post. Otherwise you'll have to sort by the name of the element in descending order (PeopleList then KidList).<xsl:for-each select="*"> <xsl:sort select="." data-type="text" order="descending" /> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each>
Mark's blog: developMENTALmadness.blogspot.com Funniest variable name: lLongDong - spotted in legacy code, was used to determine how long a beep should be. - Dave Bacher
-
If you can't control the order of KidList and PeopleList then the result your solution will always be the order of the xml document. If KidList is first in the Xml then it will be first in your output. If you need it to be more generic then you will need to do this:
<xsl:for-each select="*"> <xsl:sort select="@order" data-type="number" /> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each>
That is assuming you are still using the "order" attribute in your xml that was in your first post. Otherwise you'll have to sort by the name of the element in descending order (PeopleList then KidList).<xsl:for-each select="*"> <xsl:sort select="." data-type="text" order="descending" /> <xsl:variable name="TemplateName" select="."/> <xsl:apply-templates select="$TemplateName"/> </xsl:for-each>
Mark's blog: developMENTALmadness.blogspot.com Funniest variable name: lLongDong - spotted in legacy code, was used to determine how long a beep should be. - Dave Bacher
Mark J. Miller wrote:
If you can't control the order of KidList and PeopleList then the result your solution will always be the order of the xml document.
Maybe I didn't explain clearly, but that is what I wanted: maintain the xml order. I thought to add the "order" attribute for sorting, but had no idea how to use it. Your code is a great help and I will use it for sure. Thanks :)