XSLT with following-sibling

Discussion in 'XML' started by peter_hanzel@yahoo.com, Feb 21, 2007.

  1. Guest

    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
     
    , Feb 21, 2007
    #1
    1. Advertising

  2. 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:eek:utput 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/
     
    Martin Honnen, Feb 21, 2007
    #2
    1. Advertising

  3. Guest

    On Feb 21, 3:52 pm, 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
     
    , Feb 21, 2007
    #3
  4. Guest

    Oki thanks a lot. That thing with xsl:key is new for me.

    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
     
    , Feb 21, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kathy Burke
    Replies:
    0
    Views:
    697
    Kathy Burke
    Aug 3, 2003
  2. Peter Rohleder
    Replies:
    3
    Views:
    7,591
    C. M. Sperberg-McQueen
    Jul 2, 2003
  3. Niall Smart
    Replies:
    1
    Views:
    1,822
    Dimitre Novatchev [MVP XML]
    Mar 5, 2004
  4. Petterson Mikael

    test of following-sibling[2] does not work

    Petterson Mikael, Feb 6, 2006, in forum: XML
    Replies:
    1
    Views:
    863
    George Bina
    Feb 6, 2006
  5. Replies:
    11
    Views:
    664
    Fredrik Lundh
    Jan 23, 2006
Loading...

Share This Page