|
Subject: Re: [xsl] Algoritm for this Hierarchy? From: "Joerg Heinicke" <joerg.heinicke@xxxxxx> Date: Sun, 3 Feb 2002 10:29:42 +0100 |
Hello Mario,
I have some questions about your XML:
1. You have for example {"fr"}, {"fr","un"}, {"fr","un","doo"}and
{"fr","un","doo","trois"}. Why storing one information/array multiple times?
2. And is the language always the last? It's always a bit critical, if the
output depends on the order of the input nodes. In my eyes for example it's
better to put the language as an attribute to the <p.array>-node.
3. In theory you don't need the size of an array. You can count the elements
in eery <p.array>.
Then my suggestion: You always have to select (apply-templates) the last <v>
in an array. And you must group the <p.array>s by it's last <v>.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<!-- grouping key -->
<xsl:key name="arrays" match="p.array" use="v[last()]"/>
<xsl:template match="r">
<xsl:copy>
<!-- select unique <p.array>s, grouped by it's language (last
<v>) -->
<xsl:apply-templates select="obj/p.array[count( . |
key('arrays',v[last()])[1] ) = 1]" mode="unique"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p.array" mode="unique">
<!-- sort all <p.array>s with this language -->
<xsl:apply-templates select="key('arrays', v[last()])">
<!-- alternatively select="count(v)" if no @size-attribute -->
<xsl:sort select="@size" order="descending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="p.array">
<!-- select only the <p.array> of this language with the most
entries -->
<xsl:if test="position() = 1">
<!-- begin with the last <v>, the language -->
<xsl:apply-templates select="v[last()]"/>
</xsl:if>
</xsl:template>
<xsl:template match="v">
<obj name="{text()}">
<!-- select the <v> backwards for order 1, 2, 3 and so on -->
<xsl:apply-templates select="preceding-sibling::v[1]"/>
</obj>
</xsl:template>
</xsl:stylesheet>
You get your wanted output with this stylesheet.
Regards,
Joerg
> Hello,
>
> I would like to convert the list of <obj> elements to
> the hierarchical XML output, as below, but am having
> problems identifying a workable algorithm. Can anyone
> suggest a simplest (or so ;-) algorithm for this?
>
> Mario Ruggier
>
> ===================================
> Input XML (<obj> elements may occur
> in any order):
>
> <r>
> <obj>
> <p.array size="1">
> <v>en</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="1">
> <v>it</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="1">
> <v>fr</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="2">
> <v>one</v>
> <v>en</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="2">
> <v>uno</v>
> <v>it</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="2">
> <v>un</v>
> <v>fr</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="3">
> <v>two</v>
> <v>one</v>
> <v>en</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="3">
> <v>due</v>
> <v>uno</v>
> <v>it</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="3">
> <v>doo</v>
> <v>un</v>
> <v>fr</v>
> </p.array>
> </obj>
> <obj>
> <p.array size="4">
> <v>trois</v>
> <v>doo</v>
> <v>un</v>
> <v>fr</v>
> </p.array>
> </obj>
> </r>
>
> ===================================
> Desired Output (order of sibling <obj>
> elements is not important):
>
> <r>
> <obj name="en">
> <obj name="one">
> <obj name="two" />
> </obj>
> </obj>
> <obj name="fr">
> <obj name="un">
> <obj name="doo">
> <obj name="trois"/>
> </obj>
> </obj>
> </obj>
> <obj name="it">
> <obj name="uno">
> <obj name="due" />
> </obj>
> </obj>
> </r>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Algoritm for this Hierarchy?, Ruggier, Mario | Thread | [xsl] Re: Re: Re: An issue with XPa, Dimitre Novatchev |
| [xsl] Re: Re: Re: An issue with XPa, Dimitre Novatchev | Date | [xsl] Need help with apply-template, Brad Cox |
| Month |