I'm trying to sort entries in an XML file using Saxon, Saxon:sort and an XSLT 3.0 stylesheet.
I need to sort the nodes by the date in the <blogger:filename> field, which has the date as part of a URL, i.e. /2011/01/post.html. The date sort can be ascending or descending.
One issue is a result of my efforts to use sort: "Error reported by XML parser: The element type "xsl:stylesheet" must be terminated by the matching end-tag". I have an end tag, but it's obviously incorrect.
My input.xml file:
<?xml version='1.0' encoding='utf-8'?> <feed xmlns='http://www.w3.org/2005/Atom' xmlns:blogger='http://schemas.google.com/blogger/2018'> <id>tag:blogger.com,1999:blog-17477</id> <title>Test Blog</title> <entry> <id>tag:blogger.com,1999:blog-17477.post-670855911</id> <blogger:type>POST</blogger:type> <blogger:status>LIVE</blogger:status> <author> <name>Author</name> <uri></uri> <blogger:type>BLOGGER</blogger:type> </author> <title>Title Title</title> <content type='html'>Content Content Content Content Content</content> <blogger:metaDescription/> <blogger:created>2011-01-05T16:33:59.731Z</blogger:created> <published>2011-01-06T12:32:00.001Z</published> <updated>2011-01-06T12:32:00.138Z</updated> <blogger:location/> <category scheme='tag:blogger.com,1999:blog-17477683' term='News'/> <blogger:filename>/2011/01/a-post.html</blogger:filename> <link/> <enclosure/> <blogger:trashed/> </entry> <entry> <id>tag:blogger.com,1999:blog-17477.post-670855911</id> <blogger:type>POST</blogger:type> <blogger:status>LIVE</blogger:status> <author> <name>Author</name> <uri></uri> <blogger:type>BLOGGER</blogger:type> </author> <title>Title Title</title> <content type='html'>Content Content Content Content Content</content> <blogger:metaDescription/> <blogger:created>2011-01-05T16:33:59.731Z</blogger:created> <published>2011-01-06T12:32:00.001Z</published> <updated>2011-01-06T12:32:00.138Z</updated> <blogger:location/> <category scheme='tag:blogger.com,1999:blog-17477683' term='News'/> <blogger:filename>/2011/01/z-post.html</blogger:filename> <link/> <enclosure/> <blogger:trashed/> </entry> <entry> <id>tag:blogger.com,1999:blog-17477.post-670855911</id> <blogger:type>POST</blogger:type> <blogger:status>LIVE</blogger:status> <author> <name>Author</name> <uri></uri> <blogger:type>BLOGGER</blogger:type> </author> <title>Title Title</title> <content type='html'>Some Content Content</content> <blogger:metaDescription/> <blogger:created>2022-01-05T16:33:59.731Z</blogger:created> <published>2022-01-06T12:32:00.001Z</published> <updated>2022-01-06T12:32:00.138Z</updated> <blogger:location/> <category scheme='tag:blogger.com,1999:blog-17477683' term='News'/> <blogger:filename>/2022/03/post.html</blogger:filename> <link/> <enclosure/> <blogger:trashed/> </entry> <entry> <id>tag:blogger.com,1999:blog-17477.post-670855911</id> <blogger:type>POST</blogger:type> <blogger:status>LIVE</blogger:status> <author> <name>Author</name> <uri></uri> <blogger:type>BLOGGER</blogger:type> </author> <title>Title Title</title> <content type='html'>Content Content Content Content Content</content> <blogger:metaDescription/> <blogger:created>2012-01-05T16:33:59.731Z</blogger:created> <published>2012-01-06T12:32:00.001Z</published> <updated>2012-01-06T12:32:00.138Z</updated> <blogger:location/> <category scheme='tag:blogger.com,1999:blog-17477683' term='News'/> <blogger:filename>/2012/06/apost.html</blogger:filename> <link/> <enclosure/> <blogger:trashed/> </entry> </feed> stylesheet.xml:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xpath-default-namespace="http://www.w3.org/2005/Atom" xmlns:blogger='http://schemas.google.com/blogger/2018' exclude-result-prefixes="#all"> <xsl:mode on-no-match="shallow-copy"/> <xsl:template match="entry[blogger:filename]"> <xsl:apply-templates select="blogger:filename"> <xsl:sort select="blogger:filename" order="descending" /> </xsl:apply-templates> </xsl:template> <xsl:output indent="yes"/><xsl:strip-space elements="*"/> </xsl:stylesheet>
<xsl:template match="entry[blogger:filename]"/>, you want<xsl:template match="entry[blogger:filename]">, to have a start tag, not a self-closing tag. Ask the sorting problem in a different, new question. Take note thatxsl:sortis only useful as a child of eitherxsl:apply-templatesorxsl:for-eachorxsl:perform-sort, it doesn't work standalone. For that XPath 3.1 has afn:sortfunction.entryelements by theirblogger:filenamechild, not theblogger:filenameelements in eachentry(as there seems to be only one)? In such case your template should match the rootfeedelement and apply templates (with sort) to itsentrychildren.<blogger:filename>per entry, and I want to sort all the entries on the contents of that node, the date. And retain all of the other nodes in the output.