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 00:55:32 -0700 |
[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 > -----Original Message----- > From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx > [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx]On Behalf Of Zack Brown > Sent: Saturday, May 04, 2002 11:08 AM > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Identifying two tags that share some attribute names and > values > > > Hi folks, > > I've been migrating the Kernel Traffic web site > (http://kt.zork.net) over to an > XML/XSLT-based production system. So far it looks like something > I should have > done years ago. Compilation time (compared with my old home-grown > processor) > has dropped from hours to minutes, and the flexibility to add new features > is just amazing. > > However, there are still a few things that are giving me > problems. One such > boils down to trying to identify a set of tags that share attributes with > a target tag. So for instance I have two files, 1.xml and 2.xml: > > ----------------------------- 1.xml --------------------------------- > <?xml version="1.0" ?> > > <mydata> > <a x="1" y="2" z="3">test</a> > </mydata> > --------------------------------------------------------------------- > > ----------------------------- 2.xml --------------------------------- > <?xml version="1.0" ?> > > <outsidedata> > <b x="1" y="2">PPP</b> > <b y="2" z="3">QQQ</b> > <b z="3">RRR</b> > <b x="9" y="8" z="7">SSS</b> > <b m="2" z="3">TTT</b> > </outsidedata> > --------------------------------------------------------------------- > > Basically, 1.xml represents a newsletter file, and 2.xml is an > automatically > generated file that contains cross-reference information. The <a> tag in > 1.xml is a cross-reference request that needs to be resolved using data > available in 2.xml. > > processing is done on 1.xml, which reads in 2.xml via the document() > function. The XSLT code analyzes 2.xml and looks for all <b> tags whose > attributes precisely match attributes found in the target <a> > tag. Note that > not all of <a>'s attributes must be present in a matching <b>, but all of > <b>'s attributes must be present in <a> and must share the same values as > the corresponding attributes in <a>. Also note that <a>'s > attributes are not > necessarily "x", "y", and "z", but could be anything. The XSLT code should > not make assumptions about their names or how many there may be. > > So in the above example files, <a> contains attributes "x", "y", and "z", > which each have the values "1", "2", and "3" respectively. > Looking at 2.xml, > you can see that the first, second and third <b> tags are > successful matches, > while the fourth and fifth are not. > > What I need is a recipe like the following (except that works ;-): > > ----------------- XSLT code for processing a.xml -------------------- > <!-- Resolve kcrefs --> > <xsl:template match="mydata/a"> > <xsl:for-each select="document('2.xml')/outsidedata/b"> > [<xsl:value-of select="."/>] > </xsl:for-each> > </xsl:template> > --------------------------------------------------------------------- > > in which the output would look something like this: > > ----------------------- Desired output ------------------------------ > [PPP] > [QQQ] > [RRR] > --------------------------------------------------------------------- > > I hope I've described this well enough. I don't even know if it's possible > to do what I'm asking for, though it seems like it should be. Any > help would > be greatly appreciated. > > Many thanks, > Zack > > -- > Zack Brown > > > 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Identifying two tags that, Zack Brown | Thread | Re: [xsl] Identifying two tags that, Zack Brown |
RE: [xsl] Sorting XML with XSL, out, Ernst Wolthaus | Date | Re: [xsl] Identifying two tags that, Jeni Tennison |
Month |