Sorting XML

Please support our XML, XSLT and XPATH advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Feb 2009
Posts: 9
Reputation: rat1973 is an unknown quantity at this point 
Solved Threads: 0
rat1973 rat1973 is offline Offline
Newbie Poster

Sorting XML

 
0
  #1
Feb 10th, 2009
I wish to perform a sort of an XML document, and have the output be in the same structure as the existing document. The reason for doing this, is I need the resulting document to be transformed into a new document.

My source XML is:

XML, XSLT and XPATH Syntax (Toggle Plain Text)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Msg xmlns="http://schemas.namespace.org/myschema/myschame.xsd" schemalocation="http://schemas.namespace.org/myschema/myschema.xsd ../myschema.xsd" schemaversion="5">
  3. <NumberofRecordsEnclosed>7</NumberofRecordsEnclosed>
  4. <Record>
  5. <EventSequenceNumber>3</EventSequenceNumber>
  6. <ReplaceRecord>
  7. <Id>
  8. <Number>1234</Number>
  9. </Id>
  10. </ReplaceRecord>
  11. </Record>
  12. <Record>
  13. <EventSequenceNumber>4</EventSequenceNumber>
  14. <ReplaceRecord>
  15. <Id>
  16. <Number>1234</Number>
  17. </Id>
  18. </ReplaceRecord>
  19. </Record>
  20. <Record>
  21. <EventSequenceNumber>5</EventSequenceNumber>
  22. <ReplaceRecord>
  23. <Id>
  24. <Number>1234</Number>
  25. </Id>
  26. </ReplaceRecord>
  27. </Record>
  28. <Record>
  29. <EventSequenceNumber>6</EventSequenceNumber>
  30. <ReplaceRecord>
  31. <Id>
  32. <Number>1234</Number>
  33. </Id>
  34. </ReplaceRecord>
  35. </Record>
  36. <Record>
  37. <EventSequenceNumber>1</EventSequenceNumber>
  38. <ReplaceRecord>
  39. <Id>
  40. <Number>5678</Number>
  41. </Id>
  42. </ReplaceRecord>
  43. </Record>
  44. <Record>
  45. <EventSequenceNumber>2</EventSequenceNumber>
  46. <ReplaceRecord>
  47. <Id>
  48. <Number>5678</Number>
  49. </Id>
  50. </ReplaceRecord>
  51. </Record>
  52. <Record>
  53. <EventSequenceNumber>7</EventSequenceNumber>
  54. <ReplaceRecord>
  55. <Id>
  56. <Number>1234</Number>
  57. </Id>
  58. </ReplaceRecord>
  59. </Record>
  60. </Msg>

I need the result of this to be:

XML, XSLT and XPATH Syntax (Toggle Plain Text)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Msg xmlns="http://schemas.namespace.org/myschema/myschame.xsd" schemalocation="http://schemas.namespace.org/myschema/myschema.xsd ../myschema.xsd" schemaversion="5">
  3. <NumberofRecordsEnclosed>7</NumberofRecordsEnclosed>
  4. <Record>
  5. <EventSequenceNumber>3</EventSequenceNumber>
  6. <ReplaceRecord>
  7. <Id>
  8. <Number>1234</Number>
  9. </Id>
  10. </ReplaceRecord>
  11. </Record>
  12. <Record>
  13. <EventSequenceNumber>4</EventSequenceNumber>
  14. <ReplaceRecord>
  15. <Id>
  16. <Number>1234</Number>
  17. </Id>
  18. </ReplaceRecord>
  19. </Record>
  20. <Record>
  21. <EventSequenceNumber>5</EventSequenceNumber>
  22. <ReplaceRecord>
  23. <Id>
  24. <Number>1234</Number>
  25. </Id>
  26. </ReplaceRecord>
  27. </Record>
  28. <Record>
  29. <EventSequenceNumber>6</EventSequenceNumber>
  30. <ReplaceRecord>
  31. <Id>
  32. <Number>1234</Number>
  33. </Id>
  34. </ReplaceRecord>
  35. </Record>
  36. <Record>
  37. <EventSequenceNumber>7</EventSequenceNumber>
  38. <ReplaceRecord>
  39. <Id>
  40. <Number>1234</Number>
  41. </Id>
  42. </ReplaceRecord>
  43. </Record>
  44. <Record>
  45. <EventSequenceNumber>1</EventSequenceNumber>
  46. <ReplaceRecord>
  47. <Id>
  48. <Number>5678</Number>
  49. </Id>
  50. </ReplaceRecord>
  51. </Record>
  52. <Record>
  53. <EventSequenceNumber>2</EventSequenceNumber>
  54. <ReplaceRecord>
  55. <Id>
  56. <Number>5678</Number>
  57. </Id>
  58. </ReplaceRecord>
  59. </Record>
  60. </Msg>

The XSL that I currently have is:

XML, XSLT and XPATH Syntax (Toggle Plain Text)
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pre="http://schemas.namespace.org/myschema/myschame.xsd">
  3. <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  4.  
  5. <xsl:template match="/">
  6. <Msg>
  7. <xsl:apply-templates select="pre:Msg">
  8. </xsl:apply-templates>
  9. </Msg>
  10. </xsl:template>
  11.  
  12. <xsl:template match="pre:Msg">
  13.  
  14.  
  15. <xsl:for-each select="pre:Record">
  16.  
  17. <xsl:sort select="pre:ReplaceRecord/pre:Id/pre:Number" />
  18. <xsl:sort select="pre:EventSequenceNumber" data-type="number"/>
  19. <xsl:copy-of select="." />
  20. </xsl:for-each>
  21.  
  22.  
  23. </xsl:template>
  24.  
  25. </xsl:stylesheet>

This is the closest I can get. It sorts my XML, but it ruins my namespace declaration. I need a way to copy the root node. When I put a 'copy-of' tag under that template, it copies the whole tree, not just the one node.

How can I copy the root node properly?

My plan is to then 'include' this xsl in another xsl. I need the sorted xml document so I can then perform the transformation on the sorted document.

The final output that I will eventually need to get is:

XML, XSLT and XPATH Syntax (Toggle Plain Text)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Msg xmlns="http://schemas.namespace.org/myschema/myschame.xsd" schemalocation="http://schemas.namespace.org/myschema/myschema.xsd ../myschema.xsd" schemaversion="5">
  3. <NumberofRecordsEnclosed>7</NumberofRecordsEnclosed>
  4. <Record>
  5. <EventSequenceNumber>7</EventSequenceNumber>
  6. <ReplaceRecord>
  7. <Id>
  8. <Number>1234</Number>
  9. </Id>
  10. </ReplaceRecord>
  11. </Record>
  12. <Record>
  13. <EventSequenceNumber>2</EventSequenceNumber>
  14. <ReplaceRecord>
  15. <Id>
  16. <Number>5678</Number>
  17. </Id>
  18. </ReplaceRecord>
  19. </Record>
  20. </Msg>

I want a unique entry (with the highest 'EventSequenceNumber') as the result. I can achieve this if my xml already is sorted by 'Number' and 'EventSequenceNumber'. My problem is that I am having issues feeding the filtering XSL with a sorted XML node.

There may be a better way to acheive my objectives, if so, please let me know. However, at this stage, I can only think of doing the transformation in two stages:
1) sort
2) filter

Assistance is greatly appreciated.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 9
Reputation: rat1973 is an unknown quantity at this point 
Solved Threads: 0
rat1973 rat1973 is offline Offline
Newbie Poster

Re: Sorting XML

 
0
  #2
Feb 11th, 2009
I have resolved this. For anyone interested in knowing the solution, it was rather easy (esspecially for those in the know), it just took me ages to resolve it due to the learning process (I was disappointed that I had no replies though - but there you go).

XML, XSLT and XPATH Syntax (Toggle Plain Text)
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pre="http://schemas.namespace.org/myschema/myschame.xsd">
  3. <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  4.  
  5. <xsl:template match="/">
  6. <xsl:apply-templates select="pre:Msg" />
  7. </xsl:template>
  8.  
  9. <xsl:template match="pre:Msg">
  10. <xsl:copy>
  11.  
  12.  
  13. <xsl:for-each select="pre:Record">
  14.  
  15. <xsl:sort select="pre:ReplaceRecord/pre:Id/pre:Number" />
  16. <xsl:sort select="pre:EventSequenceNumber" data-type="number"/>
  17. <xsl:copy-of select="."/>
  18. </xsl:for-each>
  19.  
  20. </xsl:copy>
  21.  
  22. </xsl:template>
  23.  
  24. </xsl:stylesheet>

The key points that I learnt/resolved my issue:

* copy-of -> copies children as well
* copy -> copies only the current node
* required the root node copy in the 'pre:Msg' template, not the '/' template.

Unfortunately the need of a solution does not permit one to spend as much time reading as one requires, but at least I got there in the end.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the XML, XSLT and XPATH Forum
Thread Tools Search this Thread



Tag cloud for XML, XSLT and XPATH
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC