[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Identifying two tags that share some attribute nam

Subject: Re: Identifying two tags that share some attribute names and values
From: Zack Brown <zbrown@xxxxxxxxxxxxxxx>
Date: Sun, 5 May 2002 10:08:50 -0700
xsl if test and
OUCH!

I apologize for this, but it looks like I slightly misstated the problem. I
tested your solution and it looks like exactly what I'm looking for, with one
difference: it is not <a> that contains the superset of attributes, with <b>
containing a subset. It's actually <b> that contains the superset, and <a>
contains the subset.

This variation seems to work for me:

<xsl:variable name="file2" select="document('2.xml')/outsidedata"/>
<xsl:template match="a">
  <xsl:variable name="a" select="." />
  <xsl:for-each select="$file2/b[@* = $a/@*]">
    <xsl:variable name="b" select="." />
    <xsl:variable name="test">
      <xsl:for-each select="$a/@*">
        <xsl:if test="not($b/@*[name() = name(current())] = .)">
          no attribute with the same name on element b whose value equals this one
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>
    <xsl:if test="not(string($test))">
      [<xsl:value-of select="."/>]
    </xsl:if>
  </xsl:for-each>
</xsl:template>

Thanks!!

Zack

On Sun, May 05, 2002 at 11:01:25AM +0100, Jeni Tennison wrote:
> Hi Zack,
> 
> >> I didn't get it with one expression and need the step with $test:
> >> 
> >> <xsl:variable name="file1" select="/"/>
> >> <xsl:variable name="file2" select="document('2.xml')/outsidedata"/>
> >> 
> >> <xsl:template match="/">
> >>     <xsl:apply-templates select="$file2/b"/>
> >
> > That's a problem, because 2.xml may contain thousands of entries,
> > and I don't want to process each one. I just want to process the <a>
> > from 1.xml and find any corresponding <b> in 2.xml.
> 
> To search for a b element in 2.xml that matches your criteria, you're
> going to have to process each of them in some way. I agree that's
> going to be time-consuming given you have thousands of entries. There
> are things that you could do to make it easier to search 2.xml --
> rearrange the XML so that the bs are grouped by which attributes they
> have, for example. Or carry out some filtering on 2.xml prior to using
> it with XSLT.
> 
> If you prefer to think of it as processing the a element, then have a
> template that matches the a element, then you could do so:
> 
> <xsl:template match="a">
>   <xsl:variable name="a" select="." />
>   <xsl:for-each select="$file2/b[@* = $a/@*]">
>     <xsl:variable name="test">
>       <xsl:for-each select="@*">
>         <xsl:if test="not($a/@*[name() = name(current())] = .)">
>           no attribute with the same name on element a whose value
>           equals this one
>         </xsl:if>
>       </xsl:for-each>
>     </xsl:variable>
>     <xsl:if test="not(string($test))">
>       <xsl:text />[<xsl:value-of select="." />]<xsl:text />
>     </xsl:if>
>   </xsl:for-each>
> </xsl:template>
> 
> Three minor variations on Joerg's solution here. First, I filter the b
> elements that you iterate over to only those that have an attribute
> whose value matches one of the attributes on a. That's just a rough
> filter, and it won't lower the number of visits to b elements overall,
> but it will prevent you from building up the $test variable for every
> one of them.
> 
> Second, the test in the middle is a bit simpler. Joerg used:
> 
>   $file1/a/@*[name()=name(current())][. != current()] or
>   not($file1/a/@*[name()=name(current())])
> 
> which returns true if there is an attribute on a with the same name as
> the attribute on b that you're looking at whose value is not equal to
> the attribute on b *or* there's no attribute on a with the same name
> as the attribute on b that you're looking at.
> 
> The one I've used above is:
> 
>   not($a/@*[name() = name(current())] = .)
> 
> which returns true if it is not the case that there is an attribute on
> a, with the same name as the attribute on b that you're looking at,
> whose value is the same as the attribute on b. This will therefore
> return true either if the attribute on a with the same name isn't
> equal to the value of the attribute on b, or if there's no attribute
> on a with the same name.
> 
> The second slight difference is in the value created for the $test
> variable. All that you need to test here is whether $test ends up
> having some content or not -- the only way it can have content is if
> the test were true for one of the attributes, so you can use
> test="not(string($test))" (does the $test variable not have a string
> value?). Because of this, I tend to use something meaningful as the
> string within the test -- here "no attribute with the same name on
> element a whose value equals this one" because it documents what
> you're doing a little and is helpful if you had to debug the code --
> you could print out the value of $test and get a meaningful message.
>   
> Cheers,
> 
> Jeni
> 
> ---
> Jeni Tennison
> http://www.jenitennison.com/
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 

-- 
Zack Brown

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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.