Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   XML (http://www.velocityreviews.com/forums/f32-xml.html)
-   -   XSLT with following-sibling (http://www.velocityreviews.com/forums/t392860-xslt-with-following-sibling.html)

peter_hanzel@yahoo.com 02-21-2007 01:52 PM

XSLT with following-sibling
 
Hello, I'am writing xslt transformation and want to achieve this.
I have this xml:

<Info>
<CtrlUnit>unit1</CtrlUnit>
<Freq>1</Freq>
<Freq>2</Freq>
<CtrlUnit>unit2</CtrlUnit>
<Freq>100</Freq>
</Info>

And I want to translate it to this:

<Info>
<CtrlUnit>unit1<x:br/>1<x:br/>2</CtrlUnit>
<CtrlUnit>unit2<x:br/>100</CtrlUnit>
</Info>

So to select following Freqs but only to next CtrUnit.
How can I achieve this?


I can't use XLST 2.0 with for-each-group. Only XSLT 1.1 is available


Martin Honnen 02-21-2007 02:37 PM

Re: XSLT with following-sibling
 
peter_hanzel@yahoo.com wrote:
> Hello, I'am writing xslt transformation and want to achieve this.
> I have this xml:
>
> <Info>
> <CtrlUnit>unit1</CtrlUnit>
> <Freq>1</Freq>
> <Freq>2</Freq>
> <CtrlUnit>unit2</CtrlUnit>
> <Freq>100</Freq>
> </Info>
>
> And I want to translate it to this:
>
> <Info>
> <CtrlUnit>unit1<x:br/>1<x:br/>2</CtrlUnit>
> <CtrlUnit>unit2<x:br/>100</CtrlUnit>
> </Info>
>
> So to select following Freqs but only to next CtrUnit.
> How can I achieve this?


Here is an XSLT 1.0 example:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml" version="1.0">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="unit-group" match="Freq"
use="generate-id(preceding-sibling::CtrlUnit[1])"/>

<xsl:template match="Info">
<xsl:copy>
<xsl:copy-of select="document('')/*/namespace::x"/>
<xsl:apply-templates select="CtrlUnit"/>
</xsl:copy>
</xsl:template>

<xsl:template match="CtrlUnit">
<xsl:copy>
<xsl:value-of select="."/>
<xsl:apply-templates select="key('unit-group', generate-id())"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Freq">
<x:br/><xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

Result applied to your input XML with Saxon 6.5 is

<Info xmlns:x="http://www.w3.org/1999/xhtml">
<CtrlUnit>unit1<x:br/>1<x:br/>2</CtrlUnit>
<CtrlUnit>unit2<x:br/>100</CtrlUnit>
</Info>


--

Martin Honnen
http://JavaScript.FAQTs.com/

p.lepin@ctncorp.com 02-21-2007 02:43 PM

Re: XSLT with following-sibling
 
On Feb 21, 3:52 pm, peter_han...@yahoo.com wrote:
> <Info>
> <CtrlUnit>unit1</CtrlUnit>
> <Freq>1</Freq>
> <Freq>2</Freq>
> <CtrlUnit>unit2</CtrlUnit>
> <Freq>100</Freq>
> </Info>
>
> And I want to translate it to this:
>
> <Info>
> <CtrlUnit>unit1<x:br/>1<x:br/>2</CtrlUnit>
> <CtrlUnit>unit2<x:br/>100</CtrlUnit>
> </Info>
>
> So to select following Freqs but only to next CtrUnit.


First of all, apply your evil-removal tool (I favour
shovels) to whoever designed that XML.

<Info>
<CtrlUnit name="unit1">
<Freq>1</Freq>
<Freq>2</Freq>
</CtrlUnit>
<CtrlUnit name="unit2">
<Freq>100</Freq>
</CtrlUnit>
</Info>

Is way more logical, and you wouldn't have to face your
present problems if it was designed that way from the
start.

> How can I achieve this?


However, since it is possible that you have no power over
your source XML's structure, and since grouping problems
are sometimes unavoidable anyway, here's a way to do this:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="ctrl-unit" match="Freq"
use="generate-id(preceding-sibling::CtrlUnit[1])"/>
<xsl:template match="Info">
<xsl:copy>
<xsl:apply-templates select="CtrlUnit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CtrlUnit">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates
select="key('ctrl-unit',generate-id(.))"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Freq">
<br/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

Google XSL FAQ, it has a lot of highly useful info on
grouping, as well as about a zillion other problems.

--
Pavel Lepin


peter_hanzel@yahoo.com 02-21-2007 03:18 PM

Re: XSLT with following-sibling
 
Oki thanks a lot. That thing with xsl:key is new for me.

peter_hanzel@yahoo.com napísal(a):
> Hello, I'am writing xslt transformation and want to achieve this.
> I have this xml:
>
> <Info>
> <CtrlUnit>unit1</CtrlUnit>
> <Freq>1</Freq>
> <Freq>2</Freq>
> <CtrlUnit>unit2</CtrlUnit>
> <Freq>100</Freq>
> </Info>
>
> And I want to translate it to this:
>
> <Info>
> <CtrlUnit>unit1<x:br/>1<x:br/>2</CtrlUnit>
> <CtrlUnit>unit2<x:br/>100</CtrlUnit>
> </Info>
>
> So to select following Freqs but only to next CtrUnit.
> How can I achieve this?
>
>
> I can't use XLST 2.0 with for-each-group. Only XSLT 1.1 is available




All times are GMT. The time now is 11:58 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57