xsl-list
[Top] [All Lists]

Re: [xsl] Lookup, eliminating duplicates and sorting

2006-07-19 15:28:43
xslt 1.0 - I've a set of nodes, for which I want
a. to replace some values (most will not change), then
b. eliminate the duplicates and sort them.
..............................................................................
The text nodes represent URI's and are then used to
create html links. So far I was only able to write in
2 different task what should be done in one:



One simple way to do this:

The following transformation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

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

<xsl:key name="kb" match="b[not(. = ../../e2/f/@c)]"
 use="."/>

<xsl:key name="kb" match="@b1"
 use="../../../e1/b[. = current()/../@c]"/>

 <xsl:key name="kDist" match="b | @b1"
  use="."/>

        <xsl:template match="/">
          <e3>
            <xsl:for-each select=
             "key('kb', */e1/b)[generate-id()
                               =
                                generate-id(key('kDist', .)[1])
                               ]">
              <xsl:sort/>
        
       <b2><xsl:value-of select="."/></b2>
     </xsl:for-each>
          </e3>
        </xsl:template>
</xsl:stylesheet>

when applied on the provided source xml document:

<a>
        <e1>
                <b>abc</b>
                <b>abd</b>
                <b>abe</b>
                <b>abf</b>
                <b>abg</b>
                <b>abh</b>
                <b>abd</b>
        </e1>
        <e2>
                <f c="abe" b1="abc"/>
                <f c="abf" b1="abj"/>
                <f c="abg" b1="abi"/>
                <f c="abh" b1="abi"/>
        </e2>
</a>

produces the wanted result:

<e3>
        <b2>abc</b2>
        <b2>abd</b2>
        <b2>abi</b2>
        <b2>abj</b2>
</e3>


Hope this helped.

--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.



On 7/19/06, Manfred Staudinger <manfred(_dot_)staudinger(_at_)gmail(_dot_)com> 
wrote:
Hi list,
xslt 1.0 - I've a set of nodes, for which I want
a. to replace some values (most will not change), then
b. eliminate the duplicates and sort them.
Sample input xml:
<?xml version="1.0" encoding="UTF-8" ?>
<a>
       <e1>
               <b>abc</b>
               <b>abd</b>
               <b>abe</b>
               <b>abf</b>
               <b>abg</b>
               <b>abh</b>
               <b>abd</b>
       </e1>
       <e2>
               <f c="abe" b1="abc"/>
               <f c="abf" b1="abj"/>
               <f c="abg" b1="abi"/>
               <f c="abh" b1="abi"/>
       </e2>
</a>
The input table _e1_ will be transformed using _f_ to
  <e1>
     <b>abc</b>
     <b>abd</b>
     <b>abc</b>
     <b>abj</b>
     <b>abi</b>
     <b>abi</b>
     <b>abd</b>
  </e1>
and finally should become
=== what I would like to have ===
       <e3>
               <b2>abc</b2>
               <b2>abd</b2>
               <b2>abi</b2>
               <b2>abj</b2>
       </e3>
The text nodes represent URI's and are then used to
create html links. So far I was only able to write in
2 different task what should be done in one:

<?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" indent="yes" />

<xsl:template match="node() | @*">
       <xsl:copy>
               <xsl:apply-templates select="node() | @*"/>
       </xsl:copy>
</xsl:template>
<xsl:key name="dupl" match="b" use="."/>
<xsl:template match="e1">
       <xsl:copy>
               <xsl:for-each 
select="b[count(self::b|key('dupl',self::b)[1])=1]">
                       <xsl:sort select="."/>
                       <b><xsl:value-of select="."/></b>
               </xsl:for-each>
       </xsl:copy>
</xsl:template>
<xsl:template match="e2"/>
<xsl:template match="e3"/>

<xsl:template match="node() | @*" mode="trans">
       <xsl:copy>
               <xsl:apply-templates select="node() | @*" mode="trans"/>
       </xsl:copy>
</xsl:template>
<xsl:key name="trans" match="f" use="@c"/>
<xsl:template match="e1" mode="trans">
       <xsl:copy>
               <xsl:for-each select="b">
                       <xsl:choose>
                               <xsl:when test="key('trans', .)/@b1">
                                       <b><xsl:value-of select="key('trans', 
.)/@b1"/></b>
                               </xsl:when>
                               <xsl:otherwise>
                                       <b><xsl:value-of select="."/></b>
                               </xsl:otherwise>
                       </xsl:choose>
               </xsl:for-each>
       </xsl:copy>
</xsl:template>
<xsl:template match="e2" mode="trans"/>
<xsl:template match="e3" mode="trans"/>

<xsl:template match="/">
       <xsl:apply-templates mode="trans"/>
       <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

Many thanks in advance,
Manfred

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--