Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - Converting a very flat simple xml to hierarchy xml [Thread Next] Re: Converting a very flat simple xml to hierarchy xmlTo: NULL Date: 5/2/2007 3:32:00 PM
craigg75@g... wrote:
> Been trying for a long time to make this work. Here's my starting xml:
>
> <root>
> <a>top 1</a>
> <b>b 110</b>
> <b>b 111</b>
> <b>b 112</b>
> <c>c 11</c>
> <b>b 120</b>
> <b>b 121</b>
> <c>c 12</c>
> <b>b 130</b>
> <b>b 131</b>
> <b>b 132</b>
> <b>b 133</b>
> <c>c 13</c>
> <b>b 140</b>
> <c>c 14</c>
> <a>top 2</a>
> <b>b 210</b>
> <b>b 211</b>
> <b>b 212</b>
> <c>c 21</c>
> <b>b 220</b>
> <b>b 221</b>
> <c>c 22</c>
> </root>
>
> And here is the xml I want to end up:
>
> <root>
> <a>top 1
> <c>c 11
> <b>b 110</b>
> <b>b 111</b>
> <b>b 112</b>
> </c>
> <c>c 12
> <b>b 120</b>
> <b>b 121</b>
This is a grouping problem, here is a solution:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="by-a" match="c" use="substring(., 3, 1)"/>
<xsl:key name="by-c" match="b" use="substring(., 3, 2)"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="a"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<value><xsl:value-of select="."/></value>
<xsl:apply-templates select="key('by-a', substring(., 5, 1))"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c">
<xsl:copy>
<value><xsl:value-of select="."/></value>
<xsl:apply-templates select="key('by-c', substring(., 3, 2))"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
It will produce the grouping you want although I have intentionally
choosen to deviate a bit by wrapping the 'a' and 'c' content in a
'value' element so you get e.g.
<root>
<a>
<value>top 1</value>
<c>
<value>c 11</value>
<b>b 110</b>
<b>b 111</b>
<b>b 112</b>
</c>
<c>
<value>c 12</value>
<b>b 120</b>
<b>b 121</b>
</c>
....
That way you get a clean structure, compared to the format you described
which has mixed contents (text children and element children). If you
don't want that 'value' element then simply remove it from the
templates, the grouping solution is not different.
--
Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
| ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
