Subject: Re: [xsl] XML: From flat to hierarchical with grouping From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 29 Mar 2017 13:32:19 -0000 |
You can adapt the code at http://stackoverflow.com/questions/42932880/ which gives a general approach to converting a flat sequence with level numbers into a nested hierarchy. This approach handles an arbitrary number of levels; if you only have a maximum of three then you could possibly simplify it a little. Michael Kay Saxonica > On 29 Mar 2017, at 03:12, nick public nickpubl@xxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > I need to manipolate this XML: > > <root> > <row> > <rec1> > <fld1-1/> > </rec1> > <rec2> > <fld2-1/> > </rec2> > <rec3> > <fld3-1/> > </rec3> > <rec3> > <fld3-2/> > </rec3> > <rec2> > <fld2-2/> > </rec2> > <rec3> > <fld3-3/> > </rec3> > <rec3> > <fld3-4/> > </rec3> > </row> > <row> > <rec1> > <fld1-2/> > </rec1> > <rec2> > <fld2-3/> > </rec2> > <rec3> > <fld3-5/> > </rec3> > <rec3> > <fld3-6/> > </rec3> > <rec2> > <fld2-4/> > </rec2> > <rec3> > <fld3-7/> > </rec3> > <rec3> > <fld3-8/> > </rec3> > </row> > </root> > > to convert it in this other hierarchical structure > <root_new> > <row> > <rec1> > <fld1-1/> > <rec2> > <fld2-1/> > <rec3> > <fld3-1/> > </rec3> > <rec3> > <fld3-2/> > </rec3> > </rec2> > <rec2> > <fld2-2/> > <rec3> > <fld3-3/> > </rec3> > <rec3> > <fld3-4/> > </rec3> > </rec2> > </rec1> > </row> > <row> > <rec1> > <fld1-2/> > <rec2> > <fld2-3/> > <rec3> > <fld3-5/> > </rec3> > <rec3> > <fld3-6/> > </rec3> > </rec2> > <rec2> > <fld2-4/> > <rec3> > <fld3-7/> > </rec3> > <rec3> > <fld3-8/> > </rec3> > </rec2> > </rec1> > </row> > </root_new> > > To better explain, for each <row> element I have to include in <rec1>, > just 1 per <row>, all <rec2> in same <row> and in each <rec2> all > following <rec3> until next <rec2> in same <row>. > > row-rec1-rec2-rec3-rec3-rec2-rec3 > > have to e transformed in > row > rec1 > rec2 > rec3 > rec3 > rec2 > rec3 > > <rec1>, <rec2> and <rec3> have own fields <fld*>. > > With following script > > <?xml version="1.0" encoding="utf-8"?> > <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" >> > <xsl:output method="xml" indent="yes"/> > <xsl:key name="k2" match="rec2" > use="generate-id(preceding-sibling::rec1[1])" /> > <xsl:key name="k3" match="rec3" > use="generate-id(preceding-sibling::rec2[1])" /> > > <xsl:template match="/"> > <root_new> > <xsl:apply-templates select="//root/row" /> > </root_new> > </xsl:template> > > <xsl:template match="//row"> > <xsl:copy> > <xsl:apply-templates select="rec1" /> > </xsl:copy> > </xsl:template> > > <xsl:template match="rec1"> > <xsl:copy> > <xsl:copy-of select="./*"/> > <xsl:copy-of select="key('k2', generate-id())"/> > <xsl:apply-templates select="rec2" /> > </xsl:copy> > </xsl:template> > > <xsl:template match="rec2"> > <xsl:copy> > <xsl:copy-of select="./*"/> > <xsl:copy-of select="key('k3', generate-id())"/> > </xsl:copy> > </xsl:template> > > </xsl:stylesheet> > > I can obtain this partial result > > <?xml version="1.0" encoding="utf-8"?> > <root_new> > <row> > <rec1> > <fld1-1 /> > <rec2> > <fld2-1 /> > </rec2> > <rec2> > <fld2-2 /> > </rec2> > </rec1> > </row> > <row> > <rec1> > <fld1-2 /> > <rec2> > <fld2-3 /> > </rec2> > <rec2> > <fld2-4 /> > </rec2> > </rec1> > </row> > </root_new> > > but I'm not able to include the <rec3> elements under the <rec2> that > precede them. > > Could you help me please? > > Ciao from Italy > Nicola > > > > > > -------------------------------------------------------- > > Do you need to index your XML? Try the OpenSource XMLSmartHelper Framework
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
AW: [xsl] XML: From flat to hierarc, Dr. Patrik Stellmann | Thread | [xsl] Fwd: [BigList Fwd] Re: XML: F, nick public nickpubl |
AW: [xsl] XML: From flat to hierarc, Dr. Patrik Stellmann | Date | [xsl] Fwd: [BigList Fwd] Re: XML: F, nick public nickpubl |
Month |