Subject: [xsl] Grouping From: "Christoph Naber pentium120mhz@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 21 Oct 2020 15:25:17 -0000 |
Hello xsl-list, the question of Charlie brought me to thinking about a problem and solution that I came up with a few years ago. A few words upfront: - This is a _very_ stripped down example which doesn't reflect the complete structure. I hope that I was able to retain all relevant structural attributes that shape the solution. - I included <parentA> and <parentB> in the example to account for the fact that there are at least 20 different parents where the relevant <points> can occur as childs. It's also possible that a parent holds relevant <points>, completely different nodes and also another parent. - I don't want to include <xsl:for-each-group > in every possible parent for the sake of maintainability. Because of the loads of different child nodes it seems to me atm that it's not sensible to write specialized select-statements in apply-templates. Just select="@* | node()" and let the child-nodes "somehow" take care of themselves. My solution is somewhat like the following <?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl=" http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" method="xml" encoding="UTF-8" media-type="text/xml"/> <xsl:template match="parentA"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="parentB"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> <special/> </xsl:template> <xsl:template match="@* | node()" priority="-1"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="point[@type='1']"> <xsl:message>stripped point</xsl:message> </xsl:template> <!-- in the first position or directly after a node() that is not part of the group --> <xsl:template match="point[@type='1' and ((position() = 1) or (preceding-sibling::*[1][self::point[not(@type='1')] or not(self::point)]))]" priority="10"> <xsl:variable name="first-point-not-in-group" select="following-sibling::*[self::point[not(@type='1')] or not(self::point)][1]"/> <group> <!-- apply-templates to self and everything that follows until the next point that is not part of the group --> <xsl:apply-templates select=". | following-sibling::*[generate-id(self::*) ne generate-id($first-point-not-in-group) and (every $i in preceding-sibling::point satisfies (generate-id($i) ne generate-id($first-point-not-in-group)))]" mode="grouping"/> </group> </xsl:template> <xsl:template match="node()" mode="grouping"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> I would be interested in ways to tackle this. Are there patterns for this type of grouping problem? Is it favorable to put "for-each-group" stmts all over the place? In general: are there better ways to solve this? The sample input: <base> <parentA> <element /> <point value="A-A" type="1" /> <point value="A-B" type="1" /> <point value="A-C" type="2" /> <point value="A-D" type="1" /> <point value="A-E" type="2" /> <point value="A-F" type="1" /> <point value="A-G" type="1" /> <point value="A-H" type="1" /> </parentA> <parentB> <point value="B-A" type="1" /> <point value="B-B" type="1" /> <point value="B-C" type="2" /> <element /> <point value="B-D" type="1" /> <point value="B-E" type="1" /> </parentB> </base> The expected output: <?xml version="1.0" encoding="UTF-8"?> <base> <parentA> <element/> <group> <point value="A-A" type="1"/> <point value="A-B" type="1"/> </group> <point value="A-C" type="2"/> <group> <point value="A-D" type="1"/> </group> <point value="A-E" type="2"/> <group> <point value="A-F" type="1"/> <point value="A-G" type="1"/> <point value="A-H" type="1"/> </group> </parentA> <parentB> <group> <point value="B-A" type="1"/> <point value="B-B" type="1"/> </group> <point value="B-C" type="2"/> <element/> <group> <point value="B-D" type="1"/> <point value="B-E" type="1"/> </group> </parentB> <special/> </base> Thank you in advance for any insight! Best regards Christoph Naber
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] [ANN] XSLT Two to Three Cours, Liam R. E. Quin liam | Thread | Re: [xsl] Grouping, Martin Honnen martin |
[xsl] [ANN] XSLT Two to Three Cours, Liam R. E. Quin liam | Date | Re: [xsl] Grouping, Martin Honnen martin |
Month |