[xslt] problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tjerk Wolterink

    [xslt] problem

    i have xml like this:

    <data>
    <item type="a">
    1
    </item>
    <item type="a">
    2
    </item>
    <item type="b">
    3
    </item>
    <item type="a">
    4
    </item>
    <item type="a">
    5
    </item>
    <item type="b">
    6
    </item>
    <item type="a">
    7
    </item>
    </data>

    i want some xsl toget this for $type=a:

    <output>
    <row>
    <data>1</data>
    <data>2</data>
    </row>
    <row>
    <data>4</data>
    <data>5</data>
    </row>
    <row>
    <data>7</data>
    <data></data>
    </row>
    </output>

    and for $type=b this as output:

    <output>
    <row>
    <data>3</data>
    <data>6</data>
    </row>
    </output>


    my xsl sofar:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:styleshe et version="1.0">

    <xsl:param name="type"/>

    <xsl:template match="/data">
    <xsl:for-each select="item[xc:type=$type][(position() mod 2)=1]">
    <row>
    <xsl:apply-templates select="."/>
    <xsl:apply-templates select="followi ng-sibling::*[position() &lt; 2]"/>
    </row>
    </xsl:for-each>
    </xsl:template>

    <xsl:template match="xc:medew erker">
    <data>
    <xsl:value-of select="."/>
    </data>
    </xsl:template>

    <xsl:stylesheet >


    But this does not work, because some times items of type b
    are chosen when $type equals a.

    please help
  • Soren Kuula

    #2
    Re: [xslt] problem

    > But this does not work, because some times items of type b[color=blue]
    > are chosen when $type equals a.
    >
    > please help[/color]

    Try

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:styleshe et version="1.0"
    xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">

    <xsl:param name="type" select="'a'"/>

    <xsl:template match="/data">
    <xsl:for-each select="item[@type=$type][position() mod 2 = 1]">
    <row>
    <data><xsl:appl y-templates select="."/></data>
    <data><xsl:appl y-templates
    select="followi ng-sibling::*[@type=$type][position() &lt;2]"/>$
    </row>
    </xsl:for-each>
    </xsl:template>

    </xsl:stylesheet>

    (what you following-sibling saw was not the successors in the list
    selected in for-each, but just the siblings of the current node...)

    Soren

    Comment

    • Joachim Weiß

      #3
      Re: [xslt] problem

      Tjerk Wolterink schrieb:[color=blue]
      > <xsl:template match="/data">
      > <xsl:for-each select="item[xc:type=$type][(position() mod 2)=1]">
      > <row>
      > <xsl:apply-templates select="."/>
      > <xsl:apply-templates select="followi ng-sibling::*[position()
      > &lt; 2]"/>
      > </row>
      > </xsl:for-each>
      > </xsl:template>
      >[/color]


      Soren was quicker!

      However here is my solution without foreach loops, empty element at the
      list and last but not least only one representation of the item template.


      Hope it helps!


      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:styleshe et version="1.0"
      xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <xsl:output method="xml" />

      <xsl:param name="type">a</xsl:param>
      <xsl:template match="/">
      <xsl:apply-templates />
      </xsl:template>

      <xsl:template match="data">
      <xsl:element name="output">
      <!-- simply select every second element -->
      <xsl:apply-templates select="item[@type=$type][not(position() mod
      2=0)]" mode="loop"/>
      </xsl:element>
      </xsl:template>


      <!-- item builds a group (remember only every second element is
      selected) -->
      <xsl:template match="item" mode="loop">
      <xsl:element name="group">
      <!-- buliding the data element -->
      <xsl:apply-templates select="." mode="item" />
      <!-- if there is no next item bulild an empty data element -->
      <xsl:if test="not(follo wing-sibling::item[@type=$type][1])">
      <xsl:element name="data"/>
      </xsl:if>
      <!-- now we apply a template for exactly the next item -->
      <xsl:apply-templates
      select="followi ng-sibling::item[@type=$type][1]" mode="item"/>

      </xsl:element>
      </xsl:template>

      <!-- our item template -->
      <xsl:template match="item" mode="item">
      <xsl:element name="data">
      <xsl:value-of select="." />
      </xsl:element>
      </xsl:template>

      </xsl:stylesheet>

      Comment

      • Soren Kuula

        #4
        Re: [xslt] problem

        Hi Soren,[color=blue]
        > <xsl:for-each select="item[@type=$type][position() mod 2 = 1]">
        > <row>
        > <data><xsl:appl y-templates select="."/></data>
        > <data><xsl:appl y-templates
        > select="followi ng-sibling::*[@type=$type][position() &lt;2]"/>$[/color]

        Oops, how did that final $ sign end up there? It's not supposed to be
        there, must be a typo.
        [color=blue]
        > Soren[/color]
        Soren

        Comment

        Working...