|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: XML: From flat to hierarchical with grouping
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








