xsl-list
[Top] [All Lists]

RE: How do can I select distinct nodes and adding a counter at the sa me time

2002-11-27 09:30:36
Hello Cams,

You'll have to exclude any nodes that already occur in the first file:

This concatenates the text value and the xxxx/@att value and sees if it
occurs as an @oid value in the first file.

  <xsl:apply-templates
         select="xxx[
                 (not (contains(concat(.,'||',xxxx/@*),
                      $first/mapping/@oid)) 
                  and
                  (generate-id() = generate-id(key('distinctlyXXX', 
                       self::xxx[not(xxxx/@*)]|xxxx/@*)))
                 )]"/>

You'll need to change the bits relating to the first file, to reflect its
structure:

 <xsl:variable name="first_path" select="'first.xml'"/>
 <xsl:variable name="first" select="document($first_path)/root"/>
 <xsl:variable name="first_count_maps" 
   select="count($first/mapping)"/>

hth
Tom



-----Original Message-----
From: Cams Ismael [mailto:Ismael(_dot_)Cams(_at_)siemens(_dot_)atea(_dot_)be]
Sent: 27 November 2002 15:18
To: 'xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com'
Subject: RE: [xsl] How do can I select distinct nodes and adding a
counter at the sa me time


Hello,

I have been already helped a lot by this solution. However again I
encountered a problem for which I don't see a solution 
immediately. What I
need now is a mechanism to determine if the xxx value or att1 
attribute is
already in the first xml file. When already available this 
node should not
be count. So what I want to do is the next:

first file:

      <root>
              <mapping oid=".1.5.3.2" id="1"/>
              <mapping oid=".1.5.3.4.5" id="3"/>
      </root>

second file:
      <xx>
              <xxx>.1.5.6.3.8
                 <xxxx att1=".1.5.6.3.8"/>
              <xxx>
              <xxx>.1.5.6.3.10
                 <xxxx att2="1.5.3.4.5"/>
              <xxx>
              <xxx>.1.5.6.4.5</xxx>
      </xx>

result file should be:
      <root>
              <mapping oid=".1.5.3.2" id="1"/>
              <mapping oid=".1.5.3.4.5" id="3"/>
              <mapping oid=".1.5.3.4.8" id="5"/>
              <mapping oid=".1.5.6.4.5" id="7"/>
      </root>

The solution I have now gives the following result:
      <root>
              <mapping oid=".1.5.3.2" id="1"/>
              <mapping oid=".1.5.3.4.5" id="3"/>
              <mapping oid=".1.5.3.4.8" id="5"/>
              <mapping oid=".1.5.6.4.5" id="9"/> <!--This id should be
7-->
      </root>

The stylesheet I use select all distinct values with use of the Muench
method. Than I check if the value was already available in 
the first file.
What I actually need is a selection of all distinct nodes 
that don't already
exist in the first file. If all this information was in one 
file I think I
could handle it, but no two files are used and I don't see directly a
solution for this. Hopefully someone can help me with this again ?

Thanks in advance.

Kind regards,
Ismaël

-----Original Message-----
From: TSchutzerWeissmann(_at_)uk(_dot_)imshealth(_dot_)com
[mailto:TSchutzerWeissmann(_at_)uk(_dot_)imshealth(_dot_)com]
Sent: vrijdag 22 november 2002 16:59
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: RE: [xsl] How do can I select distinct nodes and adding a
counter at the sa me time


Dear Ismaël

I know what you mean, but the problem I have is how do I 
produce a tree
with
distinct values that I can access afterwards.

This is essentially a grouping problem. You can use xsl:key to group
elements according to a particular value. This will allow you 
to access the
distinct values as a nodeset, without having to put them in a 
variable and
use an extension function.

[from your first email]

The second one looks like this:

    <xx>
            <xxx>.1.5.6.3.8
               <xxxx att1=".1.5.6.3.8"/>
            <xxx>
            <xxx>.1.5.6.3.10
               <xxxx att2="1.5.6.3.9"/>
            <xxx>
            <xxx>.1.5.6.4.5</xxx>
    </xx>
[...]
 What I want to do know is getting out of the second xml file the
values of the attributes mapped onto an odd number (5,7,9) when this
attribute is available. When not available the text value 
of the tag must
be
used. 

The only hard bit is setting up the key so that it ignores 
the text value of
the xxx tag if there's an xxxx child with an attribute.

<xsl:key name="distinctlyXXX" match="xxx" 
  use="self::xxx[not(xxxx/@*)]|xxxx/@*"/>

<!-- group on the xxxx child's first attribute, if it exists, 
     otherwise on the text value of xxx -->

<xsl:variable name="first_path" select="firstFile.xml"/>
<xsl:variable name="first" select="document($first_path)"/>
<xsl:variable name="first_count_maps" 
select="count($first/mapping/map)"/>

  <xsl:template match="xx">
    <mapping>
      <xsl:copy-of select="$first/mapping/map"/>
      <xsl:apply-templates
        select="xxx[generate-id() = generate-id(key('distinctlyXXX', 
                self::xxx[not(xxxx/@*)]|xxxx/@*))]"/>
      <!-- this is classic Muenchian grouping -->
    </mapping>
</xsl:template>

  <xsl:template match="xxx">
    <map oid="{string(self::xxx[not(xxxx/@*)] | xxxx/@*)}"
      id="{(position() + $first_map_count) * 2 - 1}">
      <xsl:value-of select=". | xxxx/@*"/>
    </map>
  </xsl:template>

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list