[xsl] How to select a node in an xpath expression ?

Subject: [xsl] How to select a node in an xpath expression ?
From: Vincent De Groote <vdg.encelade@xxxxxxxxx>
Date: Wed, 08 Dec 2010 19:25:13 +0100
Hello,

I'm using Saxon-B 9.1.0.7 (in Oxygen), with a stylesheet using version
2:

     <p>XSL version: 2.0</p>
        <p>Vendor: SAXON 9.1.0.7 from Saxonica</p>
        <p>Vendor URL: http://www.saxonica.com/</p>
        <p>Product name: SAXON</p>
        <p>Product version: 9.1.0.7</p>
        <p>Is schema-aware: no</p>
        <p>Supports serialization: yes</p>
        <p>Supports backwards compatibility: yes</p>

My input file is structured like:

<a-root-node xmlns='a-name-space'>

    <field-group ...>
       <field-sequence>
           <field name='aaa'> ... </field>
           <field name='bbb'> ... </field>
           <field name='ccc'> ... </field>
           <field name='yyy'> ... </field>
          ... A lot of other fields ...
      <field-sequence
  </field-group>

    <field-group ...>
       <field-sequence>
           <field name='aaa'> ... </field>
           <field name='bbb'> ... </field>
           <field name='ccc'> ... </field>
           <field name='zzz'> ... </field>
          ... A lot of other fields ...
      <field-sequence
  </field-group>


...


</a-root-node>

There are a lot of field-group elements.  Some of them start with the
same sequence of field elements under the field-sequence element.
The purpose of the stylesheet is to replace (known) common sequences of
fields.  These common sequences are always at the beginning of the field
list.  The common sequences are the fields with @name = ('aaa', 'bbb',
ccc') in the sample above.  There are more than one common sequence to
match and replace.

In the stylesheet, i defined the following variable, to define the list
of fields to be replaced, and their replacement value:

   <xsl:variable name="replacements">
        
        <!-- !! Store from longest to shortest sequence !! -->
        
        <replacement replace-by="abc">
            <field name='aaa'/>
            <field name='bbb'/>
            <field name='ccc'/>
        </replacement>

        <replacement replace-by="ab">
            <field name='aaa'/>
            <field name='bbb'/>
        </replacement>
        
        
        <replacement replace-by='mnop'>
            <field name='mmm'/>
            <field name='nnn'/>
            <field name='ooo'/>
            <field name='ppp'/>
            
        </replacement>

    </xsl:variable>


As you can see, the list of fields in a replacement may be a subset of a
previous replacement.  Because the longest replacement must be chosen,
their are stored in decreasing length order.


In the template matching <field-group> elements , I didn't choose an
iteration with a for-each instruction, because the for-each cannot be
"stopped" after the first match, and it could therefore produce multiple
matches.  Instead, I tried to select the correct replacement in a
variable:

<xsl:variable name='current-field-group' select='current()'/>
<xsl:variable name='replacement'
select='$replacements/replacement[field/@name =
$current-field-group/xxx:field-sequence/xxx:field[position()
&lt;=count(field)]/@name]'/>'
                
<xsl:choose>
  <xsl:when test='$replacement'>
     ...
  </xsl:when>
  <xsl:otherwise>
     ...
  </xsl:otherwise>
</xsl:choose>
 

This replacement variable is always empty.  The expected result of the
replacement predicate is to match when the sequence of
[$replacements/replacement]/field/@name is equal to the sequence of
[$current-field-group/field-sequence/]field/@name, limiting the list to
the number of fields to be replaced.  The count(field) sub-expression is
supposed to count the number of field children of the
$replacements/replacement.

Is the last sub-expression "count(field)" understood as the count of the
$current-field-group/field-sequence field children instead of the
$replacements/replacement field children ?  If this is true, how can i
select the field children of the current replacement ?

Any idea ?

Thanks for you help

Vincent De Groote

Current Thread