[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XSL, when elements don't exist

Subject: Re: XSL, when elements don't exist
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 28 Oct 2003 15:24:55 -0500
xsl if exist
Tanya,

At 02:37 PM 10/28/2003, you wrote:
I'm trying to process an XML document for which certain elements may or may
not exist.
How can I handle this?
E.g.
<xsl:if test= "element exists"></xsl:if>
<xsl:if test= "element does not exist"></xsl:if>
...

The trick to this is knowing some of the details of how XPath works.


XPath has four data types. (XSLT 1.0 adds a fifth, the result-tree-fragment, which needn't concern us here.) They are:

node sets (sets of nodes in a source document)
numbers
strings
Booleans

In addition, XPath has rules about how to convert from any of these to the others. One of these rules, for converting a node set into a Boolean, is particularly handy: if the node set contains any nodes, it's true; if it doesn't, it's false.

Since a test attribute in a conditional expects a Boolean true or false, the trick for seeing whether a node exists is simply to retrieve it. If the set of nodes you get back contains any members, it passes the truth test; if it doesn't, it fails.

As I understand it, you need to do something special when nodes like these don't exist:

<property name="d" displayname="Defer Node Expansion" value="true" />
<property name="tr" displayname="Traverse DOM" value="true" />

...this would be (assuming your context node is the PropertyGroup):


<xsl:if test="not(child::property[@displayname='Defer Node Expansion']
               or child::property[@displayname='Traverse DOM'])">

using the Boolean 'or' operator (and the not() function), or

<xsl:if test="not(child::property[@displayname='Defer Node Expansion'] |
                  child::property[@displayname='Traverse DOM'])">

using the union operator '|', which combines two node sets.

If you apply the rule for converting node sets to Booleans in each case, you can see why they do the same thing here -- even though the 'or' operator is *not* the same as the '|' operator.

Incidentally, the casting rules referred to above make it generally superfluous in XSLT to write tests such as test="string-length(normalize-space($node) = 0", since you can always do things like test="not(normalize-space($node))" and get the same answer.

I hope this helps,
Wendell



======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread
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-2013 All Rights Reserved.