Add Gramps-sorting example to XSLT post.
authorW. Trevor King <wking@drexel.edu>
Fri, 1 Jul 2011 14:32:10 +0000 (10:32 -0400)
committerW. Trevor King <wking@drexel.edu>
Fri, 1 Jul 2011 14:32:10 +0000 (10:32 -0400)
posts/XSLT.mdwn

index 512c74464982e23f211e38b9194a9ed45684e2af..03b47317078701d48f77651261a56f8d99e88a67 100644 (file)
@@ -12,10 +12,54 @@ simple [[example|chapter]] from this intro and also included a
 [[slightly more complicated setup|code]] for generating online help
 for a list of macros.
 
+XSLT is also useful for standardizing XML content.  For example, I was
+recently trying to compare to [[Gramps]] XML files, to see what had
+changed between two database backups.  Unfortunately, the backup XML
+was not sorted by `id`, so there were many diff chunks due to node
+shuffling that didn't represent any useful information.  With the
+following XSLT:
+
+    <?xml version="1.0"?>
+    <xsl:stylesheet version="1.0"
+                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+       <xsl:output method="xml" indent="yes"/>
+       <xsl:strip-space elements="*"/>
+       <!-- identity transform -->
+       <xsl:template match="@*|node()">
+               <xsl:copy>
+                       <xsl:apply-templates select="@*|node()"/>
+               </xsl:copy>
+       </xsl:template>
+       <!-- sort node children by their `id` attributes -->
+       <xsl:template match="node()">
+               <xsl:copy>
+                       <xsl:apply-templates select="@*"/>
+                       <xsl:for-each select="node()">
+                               <xsl:sort select="@id" order="ascending"/>
+                               <xsl:apply-templates select="."/>
+                       </xsl:for-each>
+               </xsl:copy>
+       </xsl:template>
+    </xsl:stylesheet>
+
+With the above saved as `sort-by-id.xsl`, you can sort `some.xml` using
+
+    $ xsltproc --nonet --novalid sort-by-id.xsl some.xml
+
+You can compare two [[Gramps]] XML files with
+
+    $ diff -u <(zcat wtk_2011-06-30b.gramps | xsltproc --nonet --novalid sort-by-id.xsl -)
+              <(zcat wtk_2011-06-30d.gramps | xsltproc --nonet --novalid sort-by-id.xsl -) | less
+
+Jesper Tverskov has a nice page about [the identity template and
+related tricks][identity] if you want more examples of quasi-copy
+transforms.
+
 [XSLT]: http://www.w3.org/TR/xslt
 [w3]: http://www.w3schools.com/xsl/
 [intro]: http://nwalsh.com/docs/tutorials/xsl/xsl/slides.html
 [xsltproc]: http://www.xmlsoft.org/XSLT/
+[identity]: http://www.xmlplease.com/xsltidentity
 
 [[!tag tags/tools]]
 [[!tag tags/web]]