Re: [xsl] Detecting presence of attributes

Subject: Re: [xsl] Detecting presence of attributes
From: Eric van der Vlist <vdv@xxxxxxxxxxxx>
Date: Mon, 05 Feb 2001 00:03:53 +0100

Peter Flynn wrote:
> 
> I'm having a problem with detection of the presence of attributes.
> If I say
> <xsl:if test="@foo=''"> then I would expect the condition to be true if
> (a) the attribute foo was specified but the value was the null string
> "", or
> (b) the attribute foo was not specified at all.

No. The XPath rec specifies [1]:

If one object to be compared is a node-set and the other is a string,
then the comparison will be true if and only if there is a node in the
node-set such that the result of performing the comparison on the
string-value of the node and the other string is true.

This is our case here: @foo is a node-set and '' a string and in your
(b), there is no node in the node-set and the comparaison needs to
return false. 

[1] http://www.w3.org/TR/xpath#booleans

> xt does not appear to honor either. Is this a bug in xt, or have
> I missed
> some additional piece of syntax. What I want is the equivalent to
> Omnimark's condition `when attribute foo is specified'.

XT honors (a) and not (b) and that's the right behavior.

To get the feature you want to have, you need to convert the node-set
into a string first:

<xsl:if test="string(@foo)=''"> 
or
<xsl:if test="not(string(@foo))">

will do the trick.
 
> A second problem arises with the position() function. In xt this appears
> only to work within an <xsl:for-each> loop, not in a node group
> instantiated by a match or select. Is this a bug or just my misreading?

I don't see this either.

Here is a sample showing the 2 features you're complaining for tested
with latest XT:

XML:

<?xml version="1.0" encoding="UTF-8"?>
<test>
	<bar/>
	<bar foo=""/>
	<bar foo="something"/>
</test>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <xsl:template match="/">
  <result>
   <xsl:apply-templates select="test/bar"/>
  </result>
 </xsl:template>

 <xsl:template match="bar">
  <bar position="{position()}">
   <xsl:if test="@foo">
    <found>attribute foo is defined</found>
   </xsl:if>
   <xsl:if test="@foo=''">
    <found>attribute foo is empty</found>
   </xsl:if>
   <xsl:if test="not(string(@foo))">
    <found>value of attribute foo is empty</found>
   </xsl:if>
  </bar>
 </xsl:template>
</xsl:stylesheet>

Result:

<?xml version="1.0" encoding="utf-8"?>
<result>
<bar position="1">
<found>value of attribute foo is empty</found>
</bar>
<bar position="2">
<found>attribute foo is defined</found>
<found>attribute foo is empty</found>
<found>value of attribute foo is empty</found>
</bar>
<bar position="3">
<found>attribute foo is defined</found>
</bar>
</result>

Hope this helps.

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

-- 
------------------------------------------------------------------------
Eric van der Vlist       Dyomedea                    http://dyomedea.com
http://xmlfr.org         http://4xt.org              http://ducotede.com
------------------------------------------------------------------------

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


Current Thread