473,396 Members | 1,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

[XSL] Obtaining an attribute from self or ancestor

Hello!

Let's suppose we have an XML with some nested NODE nodes:

<root attr="first">
<node id="1" attr="mike">
<node id="2" />
<node id="3" attr="dave" />
</node>
<node id="4">
<node id="5" attr="peter" />
</node>
</root>

What I want to achieve is to have an XSL that:
- takes a $id variable externally from a PHP script
- finds the node with @id=$id
- outputs the value "@attr" attribute IF PRESENT, otherwise the parent's
"@attr" attribute IF PRESENT, otherwise the grandparent's... recursively
traversing from parent to parent, until an @attr value is found

This won't work for some nodes:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:output method="html" />
<xsl:template match="root">
<xsl:apply-templates select="//node[@id=$id]" />
</xsl:template>
<xsl:template match="node">
<xsl:choose>
<xsl:when test="not(@attr)"><xsl:apply-templates ".." /></xsl:when>
<xsl:otherwise><xsl:value-of select="@attr" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Oct 21 '08 #1
7 6279
Ebenezer wrote:
What I want to achieve is to have an XSL that:
- takes a $id variable externally from a PHP script
- finds the node with @id=$id
- outputs the value "@attr" attribute IF PRESENT, otherwise the parent's
"@attr" attribute IF PRESENT, otherwise the grandparent's... recursively
traversing from parent to parent, until an @attr value is found

This won't work for some nodes:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:output method="html" />
You need to define the id parameter
<xsl:param name="id"/>
<xsl:template match="root">
<xsl:apply-templates select="//node[@id=$id]" />
</xsl:template>
<xsl:template match="node">
<xsl:choose>
<xsl:when test="not(@attr)"><xsl:apply-templates ".."
/></xsl:when>
That is not the correct syntax, you need
<xsl:apply-templates select=".."/>
Also it is not clear what you want to do if you do not find a 'node'
ancestor element with an 'attr' attribute.
If you walk up to the 'root element then the template matching that will
lead to infinite recursion. So perhaps you should better use
<xsl:apply-templates select="parent::node"/>
Or if you want to walk up to the 'root' element as well you need a mode e.g.
<xsl:apply-templates select=".." mode="attribute-check"/>

and then you need to add that mode parameter to the template e.g.
<xsl:template match="root">
<xsl:apply-templates select="//node[@id=$id]"
mode="attribute-check" />
</xsl:template>
<xsl:template match="node | root" mode="attribute-check">
<xsl:choose>
<xsl:when test="not(@attr)"><xsl:apply-templates
select="parent::*" /></xsl:when>
<xsl:otherwise><xsl:value-of select="@attr" /></xsl:otherwise>
</xsl:choose>
</xsl:template>


--

Martin Honnen
http://JavaScript.FAQTs.com/
Oct 21 '08 #2
Martin Honnen ha scritto:
Ebenezer wrote:
>What I want to achieve is to have an XSL that:
- takes a $id variable externally from a PHP script
- finds the node with @id=$id
- outputs the value "@attr" attribute IF PRESENT, otherwise the
parent's "@attr" attribute IF PRESENT, otherwise the grandparent's...
recursively traversing from parent to parent, until an @attr value is
found

This won't work for some nodes:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:output method="html" />

You need to define the id parameter
<xsl:param name="id"/>
Are you sure? I don't know if it's a standard behaviour, but other
stylesheet's I've made take the parameters with no effort or definition...
That is not the correct syntax, you need
<xsl:apply-templates select=".."/>
Sorry, that was my mistake in pasting the code, it's with "select" indeed...
Also it is not clear what you want to do if you do not find a 'node'
ancestor element with an 'attr' attribute.
If you walk up to the 'root element then the template matching that will
lead to infinite recursion. So perhaps you should better use
<xsl:apply-templates select="parent::node"/>
Yes! There was an infinite recursion indeed but I didn't find a clue on
it...
Or if you want to walk up to the 'root' element as well you need a mode
e.g.
<xsl:apply-templates select=".." mode="attribute-check"/>

and then you need to add that mode parameter to the template e.g.
This info was really valuable. Thanks a lot and excuse me for the multipost.
Oct 21 '08 #3

Ebenezer <va*********@spam.comwrote in
<bR******************@twister2.libero.it>:
<root attr="first">
<node id="1" attr="mike">
<node id="2" />
<node id="3" attr="dave" />
</node>
<node id="4">
<node id="5" attr="peter" />
</node>
</root>

What I want to achieve is to have an XSL that:
- takes a $id variable externally from a PHP script
- finds the node with @id=$id
- outputs the value "@attr" attribute IF PRESENT,
otherwise the parent's "@attr" attribute IF PRESENT,
otherwise the grandparent's... recursively traversing from
parent to parent, until an @attr value is found
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="id"/>
<xsl:template match="/">
<xsl:value-of select=
"(//node[@id=$id]/ancestor-or-self::*/@attr)[last()]"
/>
</xsl:template>
</xsl:stylesheet>

HTH, HAND.

--
If we want the average quality of computer programs to rise
by 1000%, all we have to do is carefully to select 90% of
the world's programmers, and shoot them. --Richard
Heathfield in <Sf******************************@bt.com>
Oct 21 '08 #4
Actually, this can be achieved with a single XPath one-liner (even without
XSLT being involved).

Use:

//node[@id = $id]/ancestor-or-self::*[@attr][1]/@attr
Cheers,
Dimitre Novatchev
"Ebenezer" <va*********@spam.comwrote in message
news:bR******************@twister2.libero.it...
Hello!

Let's suppose we have an XML with some nested NODE nodes:

<root attr="first">
<node id="1" attr="mike">
<node id="2" />
<node id="3" attr="dave" />
</node>
<node id="4">
<node id="5" attr="peter" />
</node>
</root>

What I want to achieve is to have an XSL that:
- takes a $id variable externally from a PHP script
- finds the node with @id=$id
- outputs the value "@attr" attribute IF PRESENT, otherwise the parent's
"@attr" attribute IF PRESENT, otherwise the grandparent's... recursively
traversing from parent to parent, until an @attr value is found

This won't work for some nodes:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:output method="html" />
<xsl:template match="root">
<xsl:apply-templates select="//node[@id=$id]" />
</xsl:template>
<xsl:template match="node">
<xsl:choose>
<xsl:when test="not(@attr)"><xsl:apply-templates ".." /></xsl:when>
<xsl:otherwise><xsl:value-of select="@attr" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Oct 24 '08 #5
In article <49***********************@read.cnntp.org>,
Dimitre Novatchev <dn********@cnntp.orgwrote:
>Actually, this can be achieved with a single XPath one-liner (even without
XSLT being involved).

Use:

//node[@id = $id]/ancestor-or-self::*[@attr][1]/@attr
Or, if you find it clearer not to repeat @attr:

(//node[@id = $id]/ancestor-or-self::*/@attr)[last()]

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Oct 24 '08 #6

"Richard Tobin" <ri*****@cogsci.ed.ac.ukwrote in message
news:gd***********@pc-news.cogsci.ed.ac.uk...
In article <49***********************@read.cnntp.org>,
Dimitre Novatchev <dn********@cnntp.orgwrote:
>>Actually, this can be achieved with a single XPath one-liner (even without
XSLT being involved).

Use:

//node[@id = $id]/ancestor-or-self::*[@attr][1]/@attr

Or, if you find it clearer not to repeat @attr:

(//node[@id = $id]/ancestor-or-self::*/@attr)[last()]
This may be "clearer" but risks to be less efficient.

Using [1] in a reverse axis is a strong optimization hint and a clever XPath
engine will not traverse the whole way up -- it wil just stop on the first
self-or-ancestor element found that has an "attr" attribute.

Cheers,
Dimitre Novatchev
Oct 25 '08 #7
In article <49***********************@read.cnntp.org>,
Dimitre Novatchev <dn********@cnntp.orgwrote:
> (//node[@id = $id]/ancestor-or-self::*/@attr)[last()]
>This may be "clearer" but risks to be less efficient.

Using [1] in a reverse axis is a strong optimization hint and a clever XPath
engine will not traverse the whole way up -- it wil just stop on the first
self-or-ancestor element found that has an "attr" attribute.
True, but unlikely to be significant when the axis is ancestor-or-self,
because XML documents tend to be much shallower than they are wide.
For preceding-sibling it would be much more likely to make a difference.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Oct 25 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Iain | last post by:
I want to create an XML configuration file which might look like <REGION Name="Europe" WingDing="Blue"> <COUNTRY Name="UK" WingDing="white"> <TOWN Name="London" WingDing="Orange" /> </COUNTRY>...
3
by: Simon | last post by:
Hi, I have generated an xml document, and would like to be able to transform it to another such that the contents of a chosen node type are flattened (i.e. tags removed). e.g. <shop>...
6
by: tsirman | last post by:
hello can i put in an xsl file variables from php??? well i have 15 xsl files which have many "<a href.........." with the url of the project. so if i want to make my project portable i must have...
6
by: oooooo0000000 | last post by:
I have an XML file of varying nesting depth... <catalouge> <item id="1"> <name/> <item id="23"> <name/> <item id="55"> <name/> </item>
5
by: eric | last post by:
Hi,everyone: I have my xml data defined as xml data definition I: <?xml version="1.0"?> <parents> <parent> <id>1000</id>
0
by: james | last post by:
Hi there! I'm trying to convert an HTML file to CSS and I have problems reading the CSS attributes. For example: for table attribute: <xsl:attribute-set name="table.data"> <xsl:attribute...
1
by: james | last post by:
Hi there, I'm using the FOP from xml.apache.org/fop tool to convert from HTML to PDF. I'm reading the height and valign attributes of a column-cell (TD) in the XSL file:
2
by: Tjerk Wolterink | last post by:
I have xml like this: <data> <binding nodeset="/data/set1/value"/> <set1> <value name="a" value="3"/> </set1> </data>
2
by: cephelo | last post by:
I have no problems outputting the attribute value when the node is in context, for example, @id when an <status> node is in context. However, I am having trouble outputting it in a <xsl:value-of...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.