1

I have generated an XmlDocument and populated it with the recursive traversal of a file path. The document looks more or less like this:

<?xml version="1.0" encoding="utf-16"?>
<Tree>
  <Directory name="Root" path="C:\Root">
    <Directory name="1" path="C:\Root\1">
      <Directory name="3" path="C:\Root\1\3">
        <File name="5.png" size="198525440" path="C:\Root\1\3\5.png" />
        <File name="6.png" size="736621" path="C:\Root\1\3\6.png" />
      </Directory>
      <File name="2.png" size="761944" path="C:\Root\1\2.png" />
      <File name="3.png" size="2663" path="C:\Root\1\3.png" />
    </Directory>
    <Directory name="2" path="C:\Root\2">
      <File name="4.png" size="324187" path="C:\Root\2\4.png" />
    </Directory>
    <File name="1.png" size="2663" path="C:\Root\1.png" />
  </Directory>
</Tree>

For the directory structure:

C:
C:\Root
C:\1
C:\1\3
C:\1\3\5.png
C:\1\3\6.png
C:\1\2.png
C:\1\3.png
C:\2
C:\2\4.png
C:\1.png

Given the above tree, the goal is to write the tree to the console, in Human readable form as follows:

Root/
    +-- 1/
    |    +-- 3/
    |    |    +-- 5.png
    |    |    +-- 6.png
    |    +-- 2.png
    |    +-- 3.png
    |    +-- 2/
    |    |    +-- 4.png
    +-- 1.png

Now, I can quite easily write a function that recurses the structure, outputting the required text, but I'm thinking that XSLT could potentially transform the XmlDocument into the form shown above in a somewhat simpler way. The only question I would ask is... how? I'm a bit of a noob when it comes to XSLT (meaning, a total noob). I'm thinking use of a transform would be a more flexible method to hard coding a traverse and output function.

Further to this, it would be nice to be able to sort the XML tree by either name or file size, whilst retaining the file tree structure (sort children of each node). Can this be done with XSLT, or should I code my own IComparer to do this?

Thanks for any assistance you can give me.

1 Answer 1

1

Sorting the document can be easily done with XSLT, here is an XSLT 1.0 stylesheet that sorts any Directory child elements by the name attribute and any File child elements by an attribute name set with a parameter:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:param name="sort-key" select="'size'"/>
  <xsl:param name="sort-type" select="'number'"/>
  <xsl:param name="sort-order" select="'ascending'"/>

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <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="Directory">
        <xsl:sort select="@name"
                  data-type="text"
                  order="{$sort-order}"/>
      </xsl:apply-templates>
      <xsl:apply-templates select="File">
        <xsl:sort select="@*[local-name() = $sort-key]"
                  data-type="{$sort-type}"
                  order="{$sort-order}"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Martin. It looks even more incomprehensible than Perl is to me!
Ok, I'm going to mark this as the answer as I think the original question is unreasonably asking you to teach me everything there is to know about XSLT!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.