[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: "Evan Lenz" <evan@xxxxxxxxxxxx>
Date: Mon, 6 May 2002 00:55:32 -0700
xpath 1.0 node name
[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:  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

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-2011 All Rights Reserved.