[xsl] Re: building a hierarchical classification out of flat and redundant data

Subject: [xsl] Re: building a hierarchical classification out of flat and redundant data
From: "mnews-xsl@xxxxxx" <mnews-xsl@xxxxxx>
Date: Wed, 26 Jul 2006 12:57:46 +0200
Hello,
you might try replacing the second key 'content' with a copy template:

<xsl:template match="unit">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates select="child::node()[1]" mode="copy"/>
		<xsl:apply-templates select="subunit"/>
	</xsl:copy>
</xsl:template>

<xsl:template match="subunit|sub-subunit|sub-sub-subunit">
	<xsl:copy>
		<title><xsl:value-of select="."/></title>
		<xsl:apply-templates select="following-sibling::node()[1]" mode="copy"/>
		<xsl:apply-templates select="key('ptr-down', generate-id(.))"/>
	</xsl:copy>
</xsl:template>

<xsl:template match="node()" mode="copy">
	<xsl:copy-of select="current()"/>
	<xsl:apply-templates select="following-sibling::node()[1]" mode="copy"/>
</xsl:template>

<xsl:template match="subunit|sub-subunit|sub-sub-subunit" mode="copy"/>



Albert Juhi wrote:
Hi,

I have been trying the code, and the output it's not that I expect
because the tag subunit is identet inside another subunit like this

</sub-sub-subunit>
</sub-subunit>
</sub-subunit>
</sub-subunit>
</sub-subunit>
</sub-subunit>
</sub-subunit>

And there are duplicated nodes

But the use of the key to mark set of block is very interesting.

Thank you.



2006/7/26, Albert Juhi <albertjuhe@xxxxxxxxx>:
Hi,

Now, I try it
Seems much easy with keys.Thank you.

2006/7/25, mnews-xsl@xxxxxx <mnews-xsl@xxxxxx>:
> Hi Albert,
> there's an opportunity to solve your problem much easier:
> Bye.
>
>
> <?xml version="1.0" encoding="iso-8859-1"?>
> <xsl:stylesheet version="1.0"
>     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
> <xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>
>
> <xsl:key name="ptr-down" match="sub-subunit"
>        use="generate-id(preceding-sibling::subunit[1])"/>
> <xsl:key name="ptr-down" match="sub-sub-subunit"
>        use="generate-id(preceding-sibling::sub-subunit[1])"/>
>
> <xsl:key name="content"
>        match="node()
>                [not(self::subunit or self::sub-subunit or
self::sub-sub-subunit)]"
>        use="generate-id(
>                        (parent::unit |
>                                preceding-sibling::*
>                                        [self::subunit or
self::sub-subunit or self::sub-sub-subunit][1]
>                        )[last()])"/>
>
> <xsl:strip-space elements="*"/>
>
> <xsl:template match="/modul">
>        <xsl:copy>
>                <xsl:apply-templates/>
>        </xsl:copy>
> </xsl:template>
>
> <xsl:template match="unit">
>        <xsl:copy>
>                <xsl:copy-of select="@*"/>
>                <xsl:copy-of select="key('content', generate-id(.))"/>
>                <xsl:apply-templates select="subunit"/>
>        </xsl:copy>
> </xsl:template>
>
> <xsl:template match="subunit|sub-subunit|sub-sub-subunit">
>        <xsl:copy>
>                <title><xsl:value-of select="."/></title>
>                <xsl:copy-of select="key('content', generate-id(.))"/>
>                <xsl:apply-templates select="key('ptr-down',
generate-id(.))"/>
>        </xsl:copy>
> </xsl:template>
>
> </xsl:stylesheet>
>
> Albert Juhi wrote:
> > Hi David,
> >
> > The last week an amazin brown arrive me, the problem is the same:
> > I have this xml:
> >
> > <modul>
> > <unit id="1">
> > <subunit>Rupturas</subunit>
> > <sub-subunit>sistema </sub-subunit>
> > <sub-subunit>incertidumbre</sub-subunit>
> > <subunit>Megatendencias</subunit>
> > <sub-subunit>Caracterizacisn</sub-subunit>
> > <sub-sub-subunit>1.2.1.1.</sub-sub-subunit>
> > <p>Text 1211</p>
> > <param>Text 2 1211</param>
> > <sub-sub-subunit>1.2.1.2.</sub-sub-subunit>
> > <sub-sub-subunit>1.2.1.3.</sub-sub-subunit>
> > <sub-subunit>Vectores</sub-subunit>
> > <sub-sub-subunit>1.2.2.1.</sub-sub-subunit>
> > <sub-sub-subunit>1.2.2.2.</sub-sub-subunit>
> > <sub-sub-subunit>1.2.2.3.</sub-sub-subunit>
> > <subunit>Perspectivas</subunit>
> > <sub-subunit>Ideologmas</sub-subunit>
> > <sub-sub-subunit>1.3.1.1.</sub-sub-subunit>
> > <sub-sub-subunit>1.3.1.2.</sub-sub-subunit>
> > <sub-subunit>controversia</sub-subunit>
> > <sub-sub-subunit>1.3.2.1.</sub-sub-subunit>
> > <sub-sub-subunit>1.3.2.2.</sub-sub-subunit>
> > </unit>
> > <unit id="2">
> > <p>Desafmos sociolaboral</p>
> > <subunit>Cantidad</subunit>
> > <p>Text Cantidad</p>
> > <sub-subunit>riqueza</sub-subunit>
> > <sub-subunit>paramso</sub-subunit>
> > <sub-subunit>materia</sub-subunit>
> > <sub-subunit>panorama a las perspectivas</sub-subunit>
> > <subunit>Calidad</subunit>
> > <sub-subunit>Polarizacisn</sub-subunit>
> > <sub-subunit>La cara</sub-subunit>
> > <sub-subunit>La cruz</sub-subunit>
> > <sub-subunit>Precarizacisn</sub-subunit>
> > <subunit>experiencia</subunit>
> > <sub-subunit>Ejes</sub-subunit>
> > <sub-subunit>Condiciones</sub-subunit>
> > <sub-sub-subunit>2.3.2.1.</sub-sub-subunit>
> > <sub-sub-subunit>2.3.2.2.</sub-sub-subunit>
> > <sub-sub-subunit>2.3.2.3.</sub-sub-subunit>
> > <subunit>paradigma</subunit>
> > <sub-subunit>civilizacisn</sub-subunit>
> > <sub-subunit>emplemsmo</sub-subunit>
> > <sub-subunit>Agenda</sub-subunit>
> > </unit>
> > </modul>
> >
> > And I have to convert in a hierarchial xml structure into the unit
> > tag, with this conditions:
> > - Between tag can exists another tags, this tags belongs to the
> > preceding-sibling.
> > - The hierarchi is: unit, subunit,sub-subunit and sub-sub-subunit.
> >
> > Result file and solution:
> >
> > <modul>
> >     <unit id="1">
> >         <subunit>
> >             <title>Rupturas</title>
> >             <sub-subunit>
> >                 <title>sistema </title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>incertidumbre</title>
> >             </sub-subunit>
> >         </subunit>
> >         <subunit>
> >             <title>Megatendencias</title>
> >             <sub-subunit>
> >                 <title>Caracterizacisn</title>
> >                 <sub-sub-subunit>
> >                     <title>1.2.1.1.</title>
> >                     <p>Text 1211</p>
> >                     <param>Text 2 1211</param>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.2.1.2.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.2.1.3.</title>
> >                 </sub-sub-subunit>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>Vectores</title>
> >                 <sub-sub-subunit>
> >                     <title>1.2.2.1.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.2.2.2.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.2.2.3.</title>
> >                 </sub-sub-subunit>
> >             </sub-subunit>
> >         </subunit>
> >         <subunit>
> >             <title>Perspectivas</title>
> >             <sub-subunit>
> >                 <title>Ideologmas</title>
> >                 <sub-sub-subunit>
> >                     <title>1.3.1.1.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.3.1.2.</title>
> >                 </sub-sub-subunit>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>controversia</title>
> >                 <sub-sub-subunit>
> >                     <title>1.3.2.1.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>1.3.2.2.</title>
> >                 </sub-sub-subunit>
> >             </sub-subunit>
> >         </subunit>
> >     </unit>
> >     <unit id="2">
> >         <p>Desafmos sociolaboral</p>
> >         <subunit>
> >             <title>Cantidad</title>
> >             <p>Text Cantidad</p>
> >             <sub-subunit>
> >             <title>riqueza</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >             <title>paramso</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >             <title>materia</title>
> >         </sub-subunit>
> >         <sub-subunit>
> >             <title>panorama a las perspectivas</title>
> >             </sub-subunit>
> >         </subunit>
> >         <subunit>
> >             <title>Calidad</title>
> >             <sub-subunit>
> >                 <title>Polarizacisn</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>La cara</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>La cruz</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>Precarizacisn</title>
> >             </sub-subunit>
> >         </subunit>
> >         <subunit>
> >             <title>experiencia</title>
> >             <sub-subunit>
> >                 <title>Ejes</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>Condiciones</title>
> >                 <sub-sub-subunit>
> >                     <title>2.3.2.1.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>2.3.2.2.</title>
> >                 </sub-sub-subunit>
> >                 <sub-sub-subunit>
> >                     <title>2.3.2.3.</title>
> >                 </sub-sub-subunit>
> >             </sub-subunit>
> >         </subunit>
> >         <subunit>
> >             <title>paradigma</title>
> >             <sub-subunit>
> >                 <title>civilizacisn</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>emplemsmo</title>
> >             </sub-subunit>
> >             <sub-subunit>
> >                 <title>Agenda</title>
> >             </sub-subunit>
> >         </subunit>
> >     </unit>
> > </modul>
> >
> > This is my solution:
> >
> >     <xsl:template match="modul">
> >         <xsl:copy>
> >             <xsl:copy-of select="@*"/>
> >             <xsl:apply-templates/>
> >         </xsl:copy>
> >     </xsl:template>
> >
> >     <xsl:template match="unit">
> >         <xsl:copy>
> >             <xsl:copy-of select="@*"/>
> >             <xsl:call-template name="process-node">
> >                 <xsl:with-param name="node-father" select="name()"/>
> >             </xsl:call-template>
> >         </xsl:copy>
> >     </xsl:template>
> >
> >     <!-- Copy elements -->
> >     <xsl:template match="*">
> >         <xsl:copy>
> >             <xsl:copy-of select="@*"/>
> >             <xsl:apply-templates/>
> >         </xsl:copy>
> >     </xsl:template>
> >
> >     <!--
> >         Test if an element match with the final block using
generate-id -->
> >     <xsl:template name="get-block">
> >         <xsl:param name="context" select="."/>
> >         <xsl:param name="target"/>
> >
> >         <xsl:if test="generate-id($context)!=$target">
> >             <xsl:apply-templates select="$context" mode="copia"/>
> >             <xsl:variable name="next-element"
> > select="$context/following-sibling::*[1]"/>
> >             <xsl:if test="$next-element">
> >                 <xsl:call-template name="get-block">
> >                     <xsl:with-param name="context"
select="$next-element"/>
> >                     <xsl:with-param name="target" select="$target"/>
> >                 </xsl:call-template>
> >             </xsl:if>
> >         </xsl:if>
> >
> >     </xsl:template>
> >
> >     <!--
> >         Find a subunit tag
> >     -->
> >     <xsl:template name="process-node">
> >         <xsl:param name="context" select="*[1]"/>
> >         <xsl:param name="node-father"/>
> >
> >         <xsl:choose>
> >             <xsl:when test="$context[self::unit or self::subunit or
> > self::sub-subunit or self::sub-sub-subunit]">
> >                 <xsl:variable name="node-type"
select="name($context)"/>
> >                 <xsl:element name="{$node-type}">
> >                     <title><xsl:value-of select="$context"/></title>
> >                     <xsl:call-template name="generate-block">
> >                         <xsl:with-param name="context"
> > select="$context/following-sibling::*[1]"/>
> >                         <xsl:with-param name="node-type"
> > select="$node-type"/>
> >                     </xsl:call-template>
> >                 </xsl:element>
> >
> >                 <xsl:variable name="seguent-node"
> > select="$context/following-sibling::*[name()=$node-type][1]"/>
> >
> >                 <xsl:variable name="fathers-name">
> >                     <xsl:call-template name="get-pare">
> >                         <xsl:with-param name="unitat"
select="$node-type"/>
> >                     </xsl:call-template>
> >                 </xsl:variable>
> >
> >                 <!-- Test if are the same type and have the same
father,
> > for
> > continuing processing -->
> >                 <xsl:if test="$seguent-node and
> > name($seguent-node)=$node-type and
> >

(generate-id($seguent-node/preceding-sibling::*[name()=$fathers-name][1])=gen
erate-id($context/preceding-sibling::*[name()=$fathers-name][1]))">

> > > > <xsl:call-template name="process-node"> > > <xsl:with-param name="context" > > select="$seguent-node"/> > > </xsl:call-template> > > </xsl:if> > > > > </xsl:when> > > <xsl:otherwise> > > <xsl:apply-templates select="$context"/> > > <xsl:if test="$context/following-sibling::*"> > > <xsl:call-template name="process-node"> > > <xsl:with-param name="context" > > select="$context/following-sibling::*[1]"/> > > </xsl:call-template> > > </xsl:if> > > </xsl:otherwise> > > </xsl:choose> > > </xsl:template> > > > > <xsl:template name="generate-block"> > > <xsl:param name="context"/> > > <xsl:param name="node-type"/> > > > > <xsl:if test="$context"> > > <!-- Where stops to process? --> > > <xsl:variable name="pares"> > > <xsl:call-template name="get-ordre-unitat"> > > <xsl:with-param name="unitat" select="$node-type"/> > > </xsl:call-template> > > </xsl:variable> > > <xsl:variable name="node-limit" > > select="contains($pares,concat('*',name($context),'*'))"/> > > > > <xsl:if test="not($node-limit)"> > > <xsl:choose> > > <xsl:when test="$context[self::unit or self::subunit or > > self::sub-subunit or self::sub-sub-subunit]"> > > <xsl:call-template name="process-node"> > > <xsl:with-param name="context" > > select="$context"/> > > </xsl:call-template> > > </xsl:when> > > <xsl:otherwise> > > <xsl:apply-templates select="$context"/> > > <xsl:call-template name="generate-block"> > > <xsl:with-param name="context" > > select="$context/following-sibling::*[1]"/> > > <xsl:with-param name="node-type" > > select="$node-type"/> > > </xsl:call-template> > > </xsl:otherwise> > > </xsl:choose> > > </xsl:if> > > </xsl:if> > > > > </xsl:template> > > > > <!-- Sets the hierarchial order --> > > <xsl:template name="get-ordre-unitat"> > > <xsl:param name="unitat"/> > > > > <xsl:choose> > > <xsl:when test="$unitat='unit'"> > > <xsl:value-of select="'*unit*'"/> > > </xsl:when> > > <xsl:when test="$unitat='subunit'"> > > <xsl:value-of select="'*unit*subunit*'"/> > > </xsl:when> > > <xsl:when test="$unitat='sub-subunit'"> > > <xsl:value-of select="'*unit*subunit*sub-subunit*'"/> > > </xsl:when> > > <xsl:when test="$unitat='sub-sub-subunit'"> > > <xsl:value-of > > select="'*unit*subunit*sub-subunit*sub-sub-subunit*'"/> > > </xsl:when> > > </xsl:choose> > > > > </xsl:template> > > > > <!-- Retorna pare --> > > <xsl:template name="get-pare"> > > <xsl:param name="unitat"/> > > > > <xsl:choose> > > <xsl:when test="$unitat='unit'"> > > <xsl:value-of select="''"/> > > </xsl:when> > > <xsl:when test="$unitat='subunit'"> > > <xsl:value-of select="'unit'"/> > > </xsl:when> > > <xsl:when test="$unitat='sub-subunit'"> > > <xsl:value-of select="'subunit'"/> > > </xsl:when> > > <xsl:when test="$unitat='sub-sub-subunit'"> > > <xsl:value-of select="'sub-subunit'"/> > > </xsl:when> > > </xsl:choose> > > > > </xsl:template>

Current Thread