[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] From flat to hierarchical structure


Subject: Re: [xsl] From flat to hierarchical structure
From: "Hank Ratzesberger xml@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 22 Oct 2014 17:42:37 -0000

I have a feeling this may not be a good example, if only because it
processes all <I> elements for each iteration of <H> , but it picks up
where you started.

--Hank

<xsl:template match="root">
  <root>
    <xsl:for-each select="child::node()">
      <xsl:if test="self::H">
        <H>
          <xsl:copy-of select="@* | node()" />
            <xsl:variable name="H" select="."/>
            <xsl:for-each select="//I[starts-with(.,$H)]">
              <I><xsl:value-of select="."/></I>
            </xsl:for-each>
      </H>
    </xsl:if>
  </xsl:for-each>
 </root>
</xsl:template>

On Wed, Oct 22, 2014 at 4:23 AM, nick public nickpubl@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi people
> I need to convert a flat structure like this
>
> <root>
>    <H>1</H>
>    <I>1-1</I>
>    <I>1-2</I>
>    <I>1-3</I>
>    <H>2</H>
>    <I>2-1</I>
>    <I>2-2</I>
>  </root>
>
> in one like this
>
> <root>
>    <H>
>       1
>       <I>1-1</I>
>       <I>1-2</I>
>       <I>1-3</I>
>    </H>
>    <H>
>       2
>       <I>2-1</I>
>       <I>2-2</I>
>    </H>
> </root>
>
> I'm tring the approch for-each on the source structure in this way
>
> <?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:template match="root">
>       <root>
>          <xsl:for-each select="child::node()">
>             <xsl:if test="self::H">
>                <H>
>                   <xsl:copy-of select="@* | node()"/>
>                   <xsl:call-template name="copyI"/>
>                </H>
>             </xsl:if>
>          </xsl:for-each>
>       </root>
>    </xsl:template>
>
>    <xsl:template name="copyI">
>       <xsl:for-each select="following-sibling::node()">
>          <xsl:choose>
>
>             <xsl:when test="self::H">
>                <!-- Should be fantastic to exit from the loop! -->
>             </xsl:when>
>
>             <xsl:when test="self:(idea)">
>                <I>
>                   <xsl:copy-of select="@* | node()"/>
>                </I>
>                <xsl:text>&#13;</xsl:text>
>             </xsl:when>
>
>          </xsl:choose>
>       </xsl:for-each>
>    </xsl:template>
>
> </xsl:stylesheet>
>
> Unfortunately, the best result that I can reach is this
>
> <root>
>    <H>
>       1
>       <I>1-1</I>
>       <I>1-2</I>
>       <I>1-3</I>
>       <I>2-1</I>     wrong!
>       <I>2-2</I>     wrong!
>    </H>
>    <H>
>       2
>       <I>2-1</I>
>       <I>2-2</I>
>    </H>
> </root>
>
> where       <I>2-1</I> and <I>2-2</I> under H1 are wrong.
>
> The problem is that I cannot escape from the template copyI when it finds and H.
> Since the source structure is flat (all siblings), I'm afraid that a
> recursive copyI doesn't help.
>
> Any suggestion?
>
> Thanks a lot.
> Nicola
> 



-- 
Hank Ratzesberger
XMLWerks.com


Current Thread