Subject: Re: [xsl] Specifying element associated with attribute From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Wed, 3 Jan 2001 09:55:10 +0000 |
Hi Paul, > When you have a template that matches element nodes, it's easy to > specify choices based on particular attributes: but how do you do it > the other way around? That is, you have a template for an attribute > and you want to specify a choice based on the name of the element in > which the attribute occurs (ie. test="IF THE NAME OF YOUR ASSOCIATED > ELEMENT IS 'FOO'"). I've tried numerous permutations involving > name() and node(), but nothing has worked so far. Please, what's the > magic expression? The short answer is, use: parent::FOO The long answer follows: To go from an attribute to its element involves using the parent:: axis. So, if the context node is an attribute (as it is in a template that matches attribute nodes) then you can identify the element that attribute is on with the expression: parent::* (the element that is the parent of this node) or: parent::node() (the *node* [which actually must be an element in this context] that is the parent of this node) or the abbreviation of the above: .. To get the name of the parent, you can use the name() function, taking one of the above expressions as an argument: name(..) So, to test whether the name of the parent element is 'FOO' then you could use: name(..) = 'FOO' This answer will work perfectly well in most cases, but a better solution becomes apparent if you turn around the phrasing of what you're after. You want to know if this attribute has a 'FOO' element as a parent: is there are parent of this attribute that is a 'FOO' element? The expression to get to such a parent is: parent::FOO (the 'FOO' element that is the parent of this node). If the parent element is a 'FOO' element, then that node will be returned. If the parent element is *not* a 'FOO' element, then no node will be returned as there is no parent FOO element. Within a test expression, if a node is returned the test returns true, if no node is returned the test returns false. So (in most situations) the following are equivalent: parent::FOO is equivalent to name(..) = 'FOO' The situation where they are not equivalent is where namespaces are involved. The name() of a node gives the exact name for the node within the XML source. Look at the following XML: <foo:FOO xmlns:foo="http://www.foo.com" /> In this, the 'FOO' element is in the 'http://www.foo.com' namespace. The name() of that element is: foo:FOO So, if you are using name() to test the identity of the element, then you need to use: name(..) = 'foo:FOO' However, it might be that in another document (or even the same document!) you have an element like: <bar:FOO xmlns:bar="http://www.foo.com" /> The 'FOO' element here is in the same namespace (http://www.foo.com) but has a different prefix. Its name is: bar:FOO and it would have to be tested with: name(..) = 'bar:FOO' despite the fact that actually the two FOO elements in the two documents are meant to be precisely the same. Fortunately, when you use 'parent::FOO' instead, it takes into account the fact that the prefix of a namespace isn't important - it's the *URI* that you have to look at. If within your XSLT you have declared the 'foo' prefix to be associated with the 'http://www.foo.com' URI using: xmlns:baz="http://www.foo.com" then the XPath: parent::baz:FOO will match both the 'foo:FOO' and the 'bar:FOO' elements - it looks for the equivalence in the namespace *URI* rather than the namespace *prefix*. For this reason, it is worth getting into the habit of testing for nodes called a particular name by testing for whether the node called that name exists rather than testing whether the node is called that name. I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Specifying element associ, Evan Lenz | Thread | Re: [xsl] Specifying element associ, Mike Brown |
RE: [xsl] Saxon parser, Kay Michael | Date | RE: [xsl] Sibling Axes, Kay Michael |
Month |