Subject: [xsl] Re: topological sort From: Joerg Pietschmann <joerg.pietschmann@xxxxxx> Date: Fri, 05 Jan 2001 09:47:44 +0100 |
Hello, i finally finished a stylesheet for processing elements in topological sorted order. It is based on my original approach sent to this list some months ago. It no longer uses string lookups, is pure XSLT 1.0 and will not loop infinitely in case of circular dependencies. The trick is to carefully select elements from the document into variables so that they are node sets and cen be selected later on. The List was a great help in developing the right ideas. Training in formal logic and predicate calculus helped too, and i'm somewhat sorry that i have not yet answered Peter West's post from 2000-11-12. The complete problem is stated in an earlier post (2000-11-04) and can be found in the archive. Pseudocode: select structs with no dependencies process them repeat if not all structs are processed select structs which are not processed have only dependencies which are processed if empty stop else process them done This translates into the following stylesheet: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="structs"> <xsl:call-template name="process"> <xsl:with-param name="nodes" select="struct[not(field/type/ref)]"/> <xsl:with-param name="finished" select="/.."/> </xsl:call-template> </xsl:template> <xsl:template name="process"> <xsl:param name="nodes"/> <xsl:param name="finished"/> <xsl:variable name="processed" select="$nodes|$finished"/> <xsl:for-each select="$nodes"> <xsl:value-of select="name"/> </xsl:for-each> <xsl:if test="count(struct)>count($processed)"> <xsl:variable name="nextnodes" select="struct[not($processed/name=name) and count(field/type/ref)=count(field/type/ref[$processed/name=.])]"/> <xsl:if test="$nextnodes"> <xsl:call-template name="process"> <xsl:with-param name="nodes" select="$nextnodes"/> <xsl:with-param name="finished" select="$processed"/> </xsl:call-template> </xsl:if> </xsl:if> </xsl:template> </xsl:stylesheet> The structs are processed in increasing distance from leaves in the dependency graph. Can one of the gurus please comment on the "count(field/type/ref)=count(...)" construct, and whether this could be substituted by a possibly more efficient condition? In my real world examples with some 200+ structs it takes quite some time, if there are cheap optimisations i would appreciate it. Applying the stylesheet to the following example document gives the expected result of ACBED <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE structs [ <!ELEMENT structs (struct*)> <!ELEMENT struct (name,field*)> <!ELEMENT field (name,type)> <!ELEMENT name (#PCDATA)> <!ELEMENT type (ref|long)> <!ELEMENT ref (#PCDATA)> <!ELEMENT long EMPTY> ]> <structs> <struct> <name>A</name> <field> <name>A1</name> <type><long/></type> </field> </struct> <struct> <name>B</name> <field> <name>B1</name> <type><ref>A</ref></type> </field> <field> <name>B2</name> <type><ref>C</ref></type> </field> </struct> <struct> <name>C</name> <field> <name>C1</name> <type><long/></type> </field> </struct> <struct> <name>D</name> <field> <name>D1</name> <type><ref>E</ref></type> </field> <field> <name>D2</name> <type><ref>A</ref></type> </field> </struct> <struct> <name>E</name> <field> <name>E1</name> <type><ref>C</ref></type> </field> </struct> </structs> Will this make it into the FAQ? <grin> Regards J.Pietschmann XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] date format to dd-mm-yy f, Christopher R. Maden | Thread | Re: [xsl] Re: topological sort, Jeni Tennison |
Re: [xsl] Finding the maximun numbe, Dimitre Novatchev | Date | Re: [xsl] Finding the maximun numbe, Michael Lee |
Month |