tags:

views:

39

answers:

2

I am trying to sort an xml using xsl. Got some sample from xml.com. Its seems logical and intuitive. I tried, some how its not sorting. Its hard getting my head around this.

Here is the Xsl I am using for sorting

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>
 <xsl:template match="SharePointSites">
  <xsl:copy>
   <xsl:apply-templates>
    <xsl:sort select="Document/@Name"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="*">
  <xsl:copy>
   <xsl:apply-templates/>
  </xsl:copy>
 </xsl:template>


</xsl:stylesheet>

Below, is the XML I am trying to sort. Output is also the same. Its not obvious missing of hierarchy of tags. As I understand from xml.com sample, I have also tried specifying complete hierarchy of tags using match and select tags above.

 <SharePointSites>

<Site Url="http://workspace.imperial.ac.uk/Activities/default.aspx" Name="Activities">

<Directory Name="Public">
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/Imperial Activities Limited reg no etc.doc" Name="Imperial Activities Limited reg no etc.doc"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/Property Enqiry Form.DOC" Name="Property Enqiry Form.DOC"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/New Property Enquiry Form.doc" Name="New Property Enquiry Form.doc"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/52 Princes Gardens.pdf" Name="52 Princes Gardens.pdf"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/Silwood Web site Photo's.ppt" Name="Silwood Web site Photo's.ppt"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/Service charge.pdf" Name="Service charge.pdf"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/SPIP-G.pdf" Name="SPIP-G.pdf"/>
<Document Url="http://workspace.imperial.ac.uk/Activities/Public/Silwood Business Park pictures.doc" Name="Silwood Business Park pictures.doc"/>
</Directory>
<Directory Name="Internal"/>
</Site>
</SharePointSites>

outup is still same. Here is how I am applying transform on XML document.

XslCompiledTransform myXslTrans = new XslCompiledTransform();

            //load the Xsl 
            myXslTrans.Load(@"C:\My code\dotNet Development\SharepointXML\WebService1\SharepointSiteContent.xslt");                

            //do the actual transform of Xml document
            myXslTrans.Transform(aDoc, null, TransformedxmlWriter);

            // Set to document
            aTransforemdDoc.InnerXml = aTransformedStrbulider.ToString();
A: 

You're sorting at the wrong level. If you want to sort the documents then you need a template that matches <Directory> and contains the apply-templates with the sort.

If all you're doing is copying the input to the output with sorting, do a google search for "xsl identity transform" and add a template matching "Directory".

Here's a solution

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="Directory">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()">
        <xsl:sort select="@Name"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

At the point where you've matched Directory, and inside apply-templates, the context node is the each Document in turn. So the sort needs to be just @Name.

Detailed explanation:

  1. The first template is the 'identity template' (memorize this form, you'll use it a lot).
  2. The second template specializes handling for "Directory" nodes only.
    • The first apply-templates copies any attributes
    • The second apply-templates copies child nodes after sorting
    • Both of these templates reuse the identity transform template implicitly
Jim Garrison
comment does not have formating options. Hence posted as an answer please see my post above.
Thanks a lot Jim for detailed explanation. I learned about identity transform when you mentioned in last post, did not apply it as I wanted to resolve the issue first then attempt optimizing it. Used your xsl output is still same. Am I doing anything wrong while applying the transform? I have added the code in question body.
Cracked it. It was a silly mistake in code. Thanks again for all the help and support.
A: 

Tried this.

<xsl:template match="Directory">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort select="Document/@Name"/>
            </xsl:apply-templates>
        </xsl:copy>
</xsl:template>

Dint help output is still same, sorry for bieng thick this is my first playaround with xsl.

Next time, edit your original question to add more information. I've posted a solution in my original answer.
Jim Garrison