Re: [xsl] multiple attributes

Subject: Re: [xsl] multiple attributes
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 13 Dec 2002 11:30:26 -0800 (PST)
<DPawson@xxxxxxxxxxx> wrote in message
news:9B66BBD37D5DD411B8CE00508B69700F024A7EFD@xxxxxxxxxxxxxxxxxxxxxxxxx


> > -----Original Message-----
> > From: Américo Albuquerque [mailto:aalbuquerque@xxxxxxxxxxxxxxxx]
> > Sent: 13 December 2002 15:04
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: RE: [xsl] multiple attributes
> > 
> > 
> > Hi Dave.
> > The following stylesheet has two modes, the default checks if the
@att
> > has any of the chars entered, the block mode checks if the 
> > @att has any
> > of the words entered.
> > 
> > Example:
> > If wanted='ab' then the default mode copies all nodes that 
> > has the char
> > 'a' or the char 'b', the 'block' mode only copy the nodes that has
the
> > word 'ab' on the @att attribute.
> > If wanted='a b' (your example) then the default mode copies all
nodes
> > that has the char 'a' or the char 'b', the 'block' mode only copy
the
> > nodes that has the word 'a' or the word 'b' on the @att attribute.
> > 
> > Hope that this helps you.
> 
> Drat, my example was too simple.
>   The actual attribute values are small strings, i.e. the translate()
> function isn't applicable without some of Dimitre's magic :-)
> 
> E.g. it could be (is, in the real example)
> <element att="xml bpr training">
> 
> Sorry, I was trying to keep it clear.
>   I'll look at how you've worked it though.
> regards DaveP


Hi Dave,

Here's a solution using the "str-split-to-words" template from FXSL.


source xml (file testSplitToWords4.xml):
---------------------------------------
<t>  
  <a>  
    <element att=" xml">    
      <element att="bpr can"/>    
      <element/>    
      <element att="x"/>  
    </element>  
  </a>  
  <b/>  
  <c/>
</t>


stylesheet (file testSplitToWords4.xsl):
--------------------------------------
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:vendor="urn:schemas-microsoft-com:xslt" 
 exclude-result-prefixes="vendor"
>

   <xsl:import href="identity.xsl"/>
   <xsl:import href="strSplit-to-Words.xsl"/>

<!-- This transformation must be applied to:
        testSplitToWords4.xml               
-->

   <xsl:output indent="yes" omit-xml-declaration="yes"/>
   <xsl:strip-space elements="*"/>

   <xsl:param name="pWanted" select="'xml bpr training'"/>
    
    <xsl:template match="/">
      <xsl:variable name="vwordNodes">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="$pWanted"/>
          <xsl:with-param name="pDelimiters" select="' '"/>
        </xsl:call-template>
      </xsl:variable>
      
      <xsl:apply-templates>
        <xsl:with-param name="pattWords" 
             select="vendor:node-set($vwordNodes)/*"/>
      </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="element[@att]">
      <xsl:param name="pattWords" select="/.."/>
      
      <xsl:variable name="vAtt" select="string(@att)"/>
      
      <xsl:variable name="vContains">
        <xsl:for-each select="$pattWords">
          <xsl:if test="contains($vAtt, .)">1</xsl:if>
        </xsl:for-each>
      </xsl:variable>
      
      <xsl:if test="string($vContains)">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()">
            <xsl:with-param name="pattWords" select="$pattWords"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:if>
    
    </xsl:template>
    
</xsl:stylesheet>


Result:
------
<t>
  <a>
    <element att=" xml">
      <element att="bpr can"></element>
      <element></element>
    </element>
  </a>
  <b></b>
  <c></c>
</t>

Here the first step is to extract the wanted words using tokenisation. 

Then the node-set that contains each of the tokens is passed as a
parameter to a variation of the identity template. This template is
imported before any other templates in order to have lower priority and
not to interfere with the dynamic templates matching and selection.

identity.xsl:
------------
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    <xsl:template match="@*|node()">
      <xsl:param name="pattWords" select="/.."/>
      <xsl:copy>
        <xsl:apply-templates select="@*|node()">
          <xsl:with-param name="pattWords" select="$pattWords"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

In the first sylesheet a template for element[@att] uses the
"pattWords" parameter and checks for every token if it is contained in
the attribute "att". If any of these was true, the variable vContains
is a non-empty string and testing for this determines whether to copy
the current node or not.




=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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


Current Thread