Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 23rd, 2009, 03:03 PM
Authorized User
 
Join Date: Nov 2009
Posts: 13
Thanks: 3
Thanked 0 Times in 0 Posts
Unhappy traversing up the parent tree until condition

Want to move up the parent tree and examine an attribute on the way up. When it matches want to stop.
Want to only search till an element of a specific type is detected.

For illustration of the quest I use XML Schema:

<xsl:value-of select="ancestor-or-self::*/@maxOccurs>1 or ancestor-or-self::*/@maxOccurs='unbounded'"/>

This one searches all nodes up the tree and returns true if an ancestor with @maxOccurs>1 or unbounded exists. But that's not what I want, I want to go up but no further than xs:complexType

Basically what I intend to do is find out whether an element has maxOccurs >1 or is part of a model group with maxOccurs > 1

So in pseudo language:

function boolean is-multi( node )
begin
if node/@maxOccurs > 1 or 'unbounded'
return true
if node = 'complexType'
return false

return is-multi( node->parent )
end

As you've guessed by now, I am not a proficient XSLT programmer..
 
Old November 23rd, 2009, 03:24 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

select="ancestor-or-self::*[number(@maxOccurs) > 1 or @maxOccurs = 'unbounded' or parent::xs:complexType][1]"

will find you the innermost ancestor that satisfies one of these three conditions. I've specifed the last condition as parent::complexType to ensure that the search never goes as far as the xs:complexType element itself.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old November 23rd, 2009, 04:47 PM
Authorized User
 
Join Date: Nov 2009
Posts: 13
Thanks: 3
Thanked 0 Times in 0 Posts
Default Little problem with this..

Quote:
Originally Posted by mhkay View Post
select="ancestor-or-self::*[number(@maxOccurs) > 1 or @maxOccurs = 'unbounded' or parent::xs:complexType][1]"

will find you the innermost ancestor that satisfies one of these three conditions. I've specifed the last condition as parent::complexType to ensure that the search never goes as far as the xs:complexType element itself.
Hi Michael,
Thanks for the msg. Still some q. about this.
You correctly assumed I wanted to stop the search one level below the xs:complexType.
Further I am not sure I understand the code. You wrote number(@maxOccurs) > 1, which looks odd to me. What does it mean? Also the statement does should return boolean true if the @maxOccurs>1 or unbounded is present, false otherwise. It does not seem to do that.

Sorry for my ignorance..
Thanks again.
 
Old November 23rd, 2009, 04:58 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

number(@maxOccurs) > 1 means take the attribute node called maxOccurs, convert it to a number, and test to see if the number is greater than 1. The way number() works, if there is no such attribute or if it is not numeric, the value will be NaN, and NaN > 1 is false.

The expression I showed you will select the relevant element. Like any expression that returns a node-set, you can use it in a boolean context (for example in <xsl:if test="....">) and it will return true if the node-set is non-empty.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
dexter62 (November 24th, 2009)
 
Old November 24th, 2009, 05:08 AM
Authorized User
 
Join Date: Nov 2009
Posts: 13
Thanks: 3
Thanked 0 Times in 0 Posts
Thumbs up still a small extra..

Quote:
Originally Posted by mhkay View Post
number(@maxOccurs) > 1 means take the attribute node called maxOccurs, convert it to a number, and test to see if the number is greater than 1. The way number() works, if there is no such attribute or if it is not numeric, the value will be NaN, and NaN > 1 is false.

The expression I showed you will select the relevant element. Like any expression that returns a node-set, you can use it in a boolean context (for example in <xsl:if test="....">) and it will return true if the node-set is non-empty.
Hi Michael, thanks for your help. It works now. I had to do still a little extra because

select="ancestor-or-self::*[number(@maxOccurs) > 1 or @maxOccurs = 'unbounded' or parent::xs:complexType][1]"

selects the node that has either maxOccurs or a parent which is complexType, so need to check that again:

<xsl:variable
name="isMulti1"
select="ancestor-or-self::*[number(@maxOccurs) > 1 or @maxOccurs = 'unbounded' or parent::xs:complexType][1]"/>
<xsl:variable
name="isMulti"
select="boolean(number($isMulti1/@maxOccurs)>1 or $isMulti1/@maxOccurs='unbounded')"/>





Similar Threads
Thread Thread Starter Forum Replies Last Post
Recordset Traversing: biswa VB Databases Basics 1 October 9th, 2009 06:06 PM
traversing a tree based on an array of strings muki XSLT 1 February 16th, 2006 09:54 AM
Traversing UP my hierarchy in XPath grant6607 XSLT 1 May 11th, 2005 10:02 AM
XML Traversing using Navigator and Iterator classe jasim XML 1 July 18th, 2003 03:29 AM
passing attribute info while traversing nodes Ashley XML 1 June 20th, 2003 07:42 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.