Subject: RE: [xsl] Identifying two tags that share some attribute names and values - XPATH 2.0 SOLUTION From: "Evan Lenz" <evan@xxxxxxxxxxxx> Date: Mon, 6 May 2002 15:00:14 -0700 |
Zack Brown wrote: > Wow, a very simple solution! 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="]
["/> <!-- character reference is necessary --> <xsl:if test="$b"> <xsl:text>]</xsl:text> </xsl:if> 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] XSLT/XPath 2.0 (was "Iden, Michael Kay | Thread | RE: [xsl] Identifying two tags that, Michael Kay |
RE: [xsl] foreign characters in par, Evan Lenz | Date | Re: RE: [xsl] Saxon's handling of l, Salvatore Mangano |
Month |