RE: [xsl] Complex transform + adding an incremental integer to an attribute

Subject: RE: [xsl] Complex transform + adding an incremental integer to an attribute
From: "Mathieu Sagot" <mathieu.sagot@xxxxxxxxxxxxxxx>
Date: Thu, 23 Jun 2005 19:25:54 +0100
Jay, thank you so much for your help!
Cheers
Mathieu

-----Original Message-----
From: JBryant@xxxxxxxxx [mailto:JBryant@xxxxxxxxx]
Sent: 22 June 2005 19:33
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Complex transform + adding an incremental integer to
an attribute

Hi, Mathieu,

Against this output (yours fixed up to be well-formed XML):

<?xml version="1.0" encoding="UTF-8"?>
<n>
  <n1 id="1">
    <n2 id="1" selected="0">...</n2>
    <n2 id="2" selected="0">...</n2>
  </n1>
  <n1 id="2">
    <n2 id="1" selected="1">...</n2>
    <n2 id="2" selected="0">...</n2>
    <n2 id="3" selected="1">...</n2>
  </n1>
  <n1 id="3">
    <n2 id="1" selected="0">...</n2>
    <n2 id="2" selected="0">...</n2>
  </n1>
</n>

The following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>

  <xsl:template match="n">
    <n>
      <xsl:apply-templates/>
    </n>
  </xsl:template>

  <xsl:template match="n1[n2/@selected='1']">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="n1[not(n2/@selected='1')]">
    <xsl:variable name="number"><xsl:number
count="n1[not(n2/@selected='1')]|n2[@selected='1']" level="any"
from="n"/></xsl:variable>
    <newnode order="{$number}">
      <xsl:apply-templates/>
    </newnode>
  </xsl:template>

  <xsl:template match="n2[@selected='1']">
    <xsl:variable name="number"><xsl:number
count="n1[not(n2/@selected='1')]|n2[@selected='1']" level="any"
from="n"/></xsl:variable>
    <newnode order="{$number}"><xsl:apply-templates/></newnode>
  </xsl:template>

  <xsl:template match="n2[@selected='0' and not(../n2[@selected='1'])]">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="n2[@selected='0' and ../n2[@selected='1']]"/>

</xsl:stylesheet>

Produces the following output:

<?xml version="1.0" encoding="UTF-8"?>
<n>
     <newnode order="1">
    ...
    ...
  </newnode>

    <newnode order="2">...</newnode>

    <newnode order="3">...</newnode>

     <newnode order="4">
    ...
    ...
  </newnode>
</n>

Depending on the processor, the amount and position of whitespace
differs.
I didn't worry about white space, figuring that you could solve those
problems once you got past this one.

Tested with Saxon 8.4 and Xalan 2.4.1

Jay Bryant
Bryant Communication Services
(presently consulting at Synergistic Solution Technologies)





"Mathieu Sagot" <mathieu.sagot@xxxxxxxxxxxxxxx>
06/22/2005 12:32 PM
Please respond to
xsl-list@xxxxxxxxxxxxxxxxxxxxxx


To
<xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
cc

Subject
[xsl] Complex transform + adding an incremental integer to an attribute






 Hello list,

I have been trying to create a list of nodes containing sometimes the
parent and sometimes the childs depending on a "selected" attribute (but
then not keeping the parent).
While keeping the order the nodes came from.
+ adding an "order" attribute which is an incremental integer.

Which would give:

                 Input XML                       ->
Output XML

<n1 id=1>                        -> <newNode
order=1>...</newNode>
                 <n2 id=1 selected=0>...</n2>
                 <n2 id=2 selected=0>...</n2>
</n1>
<n1 id=2>                        -> this one is
not kept as we will keep some of the childs
                 <n2 id=1 selected=1>...</n2> -> <newNode
order=2>...</newNode>
                 <n2 id=2 selected=0>...</n2>
                 <n2 id=3 selected=1>...</n2> -> <newNode
order=3>...</newNode>
</n1>
<n1 id=3>                        -> <newNode
order=4>...</newNode>
                 <n2 id=1 selected=0>...</n2>
                 <n2 id=2 selected=0>...</n2>
</n1>


I tried to do a template select to return all the wanted nodes and then
use position() to feed the order attribute, but by using the operator |
I ended up with first all the nodes coming from n1 and then all the
nodes coming from n2, which is not the order I want them. And also the
node <n1 id=1> would be transferred although its childs are transferred.

It is a bit of a dual problem because of this order attribute, which is
incremental...

I would be happy with any clue/quidelines/ideas.
Although I am not sure if my explanations are very clear.

Anyway, I thought of a backup solution of using two xsl transform, one
to get all the nodes I want in the correct order, and an other xslt to
fill the order attribute using position()

Thank you for your time

Mathieu Sagot

Current Thread