[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 - XPATH 2.0 SOLUTION
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Tue, 7 May 2002 08:56:20 +0100
RE:  Identifying two tags that share some attribute nam
> There's actually another way you can do this that eliminates the
> xsl:for-each and uses XSLT 2.0's new "separator" attribute on 
> xsl:value-of
> as follows:
> 
>     <xsl:variable name="b" select="document('2.xml')/outsidedata/b
>                              [every $att in @* satisfies current()/@*
>                                     [.=$att and 
> name(.)=name($att)]]"/>
>     <xsl:if test="$b">
>       <xsl:text>[</xsl:text>
>     </xsl:if>
>     <xsl:value-of select="$b" separator="]&#xA;["/>
>                <!-- character reference is necessary -->
>     <xsl:if test="$b">
>       <xsl:text>]</xsl:text>
>     </xsl:if>
>

Which you can reduce further to:

<xsl:variable ... as before .../>
<xsl:if test="$b">[<xsl:value-of select="$b" 
                     separator="]&#xA;["/>]</xsl:if>

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 


> If you didn't need the outer delimiters (before the first 
> item and after the
> last item), you could get rid of the variable and xsl:if 
> tests and simply
> write:
> 
>   <xsl:value-of select="document('2.xml')/outsidedata/b
>                              [every $att in @* satisfies current()/@*
>                                     [.=$att and name(.)=name($att)]]"
>                 separator=","/>
> 
> Evan
> 
> 
> > On Mon, May 06, 2002 at 12:55:32AM -0700, Evan Lenz wrote:
> > > [NOTE: XPath 2.0 is still in Working Draft stage, subject to
> > change, and not
> > > yet ready for prime time.]
> > >
> > > While the magical expression you want cannot be expressed in
> > XPath 1.0, it
> > > can easily be expressed in XPath 2.0:
> > >
> > >
> > > document('2.xml')/outsidedata/b
> > >     [every $att in @* satisfies current()/@*
> > >          [.=$att and node-name(.)=node-name($att)]]
> > >
> > >
> > > The "every" expression is called a universal quantifier[1] and
> > enables you
> > > to test that a condition applies for *every* node in a given
> > sequence. This
> > > is something that could not be done in general in XPath 1.0.
> > >
> > > The node-name() function[2] returns an "expanded QName" type
> > that consists
> > > of a local/URI pair that can in turn be compared with other
> > expanded names.
> > > This ensures that your code is robust in the face of 
> namespace-qualified
> > > attributes without having to write 
> [local-name(.)=local-name($att) and
> > > namespace-uri(.)=namespace-uri($att)]. This is a welcome
> > shorthand indeed!
> > >
> > > Except for the node-name() function, I'm happy to report that a
> > stylesheet
> > > with this expression (using name() instead) is executed as
> > expected by Saxon
> > > 7.1. Below is the stylesheet I ran against your two files:
> > >
> > >
> > > <xsl:stylesheet version="2.0"
> > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> > >
> > >   <xsl:output method="text"/>
> > >
> > >   <xsl:template match="/">
> > >     <xsl:apply-templates select="/mydata/a"/>
> > >   </xsl:template>
> > >
> > >   <xsl:template match="/mydata/a">
> > >     <xsl:for-each select="document('2.xml')/outsidedata/b
> > >                              [every $att in @* satisfies 
> current()/@*
> > >                                     [.=$att and 
> name(.)=name($att)]]">
> > >       <xsl:text>[</xsl:text>
> > >       <xsl:value-of select="."/>
> > >       <xsl:text>]</xsl:text>
> > >       <xsl:if test="position() != last()">
> > >         <xsl:text>
> > > </xsl:text>
> > >       </xsl:if>
> > >     </xsl:for-each>
> > >   </xsl:template>
> > >
> > > </xsl:stylesheet>
> > >
> > >
> > > Invocation and output:
> > >
> > > $ java net.sf.saxon.Transform 1.xml test.xsl
> > > [PPP]
> > > [QQQ]
> > > [RRR]
> > > $
> > >
> > > With your (corrected) reformulation of the original problem, I
> > believe the
> > > expression only needs slight modification (@* trades places with
> > > current()/@*):
> > >
> > > document('2.xml')/outsidedata/b
> > >     [every $att in current()/@* satisfies @*
> > >          [.=$att and node-name(.)=node-name($att)]]
> > >
> > > Hope you found this helpful, or at least interesting!
> > >
> > > Evan
> > >
> > > [1] http://www.w3.org/TR/xpath20/#id-quantified-expressions
> > > [2] http://www.w3.org/TR/xquery-operators/#func-node-name
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 

 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.