473,327 Members | 1,936 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,327 software developers and data experts.

XSLT optional attributes

I'm not sure if this is the correct place to post this question so
please feel free to redirect me if needed.

I am writing a XSL transform document to perform a transform on an XML
document. I want some of my XML tags to have optional attributes. If the
person does not specify the value of an attribute I will assume a
default value. What is the best way to do this in XSL. Let me give an
example to make my problem clear:

foo.xml
-------

<root>
<tag attr="value"/>
<tag attr="another_value"/>
</root>

bar.xsl
-------
<xsl:template match="/root/tag">
Attribute 'attr' is <xsl:value-of select="@attr"/>
</xsl:template>

output
------
Attribute 'attr' is value
Attribute 'attr' is another_value

Now lets make one change to the above transforms. We want the attribute
'attr' to default to the value of "default" if not specified. Now one
way to do this would be:

bar.xsl
-------
<xsl:template match="/root/tag">
<xsl:choose>
<xsl:when test="@attr = ''">
Attribute 'attr' is default
</xsl:when>
<xsl:otherwise>
Attribute 'attr' is <xsl:value-of select="@attr"/>
</xsl:otherwise>
<xsl:choose>
</xsl:template>

The solution above is not really scalable. What if you want to have lots
of attributes that have defaults? And what if you are doing more than
printing a sentence out? Do you really want to repeat hundreds of lines
with just a few small changes between the different blocks of code? A
better method is if we could at the top of our template simply check if
the value is set. If it is not set then we would want to be able to set
it. My first thought was to use <xsl:variable> tag like below:

<xsl:template match="/root/tag">
<xsl:choose>
<xsl:when test="@attr = ''">
<xsl:variable name="attr" select="'default'"/>
<xsl:when>
<xsl:otherwise>
<xsl:variable name="attr" select="@attr"/>
<xsl:otherwise>
</xsl:choose>
Attribute 'attr' is <xsl:value-of select="$attr"/>
</xsl:template>

The problem is that the variable 'attr' seems to only be defined in the
context of the conditional (at least it seems to be that way in
Mozilla's XSLT processing). Once the conditional has ended (xsl:choose)
then it is no longer defined. I tried to define an empty variable 'attr'
prior to the conditional to indicate it should be defined in the scope
of the template tag not the conditional tags, but that violate the rule
of not being allowed to change a the value of a variable (by the way,
who was the idiot that thought it was a good idea to have a tag which
defines constants and call it a variable! :) ).

So does anyone have any good ideas on how I would get around this? What
is the right way to do this in XSLT?

Thanks for your suggestions,

Eric

Jul 20 '05 #1
4 4084
Hi Eric,

you are right, the scope of xsl:variable ist only the current element.
But you can place the xsl:when inside the xsl:variable

<xsl:variable name="attr">
<xsl:when test="@attr = ''">
<xsl:value-of select="'default'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@attr"/>
<xsl:otherwise>
</xsl:variable>

then it should be possible to reference to $attr afterwards in the
template. I did not tried it but I hope it works!

Peter

Eric Anderson wrote:
....
<xsl:template match="/root/tag">
<xsl:choose>
<xsl:when test="@attr = ''">
<xsl:variable name="attr" select="'default'"/>
<xsl:when>
<xsl:otherwise>
<xsl:variable name="attr" select="@attr"/>
<xsl:otherwise>
</xsl:choose>
Attribute 'attr' is <xsl:value-of select="$attr"/>
</xsl:template>

The problem is that the variable 'attr' seems to only be defined in the
context of the conditional (at least it seems to be that way in
Mozilla's XSLT processing). Once the conditional has ended (xsl:choose)
then it is no longer defined. ....
So does anyone have any good ideas on how I would get around this? What
is the right way to do this in XSLT?

Thanks for your suggestions,

Eric

Jul 20 '05 #2
In article <H3**************@fe61.usenetserver.com>,
Eric Anderson <er**@afaik.us> wrote:
<xsl:template match="/root/tag">
<xsl:choose>
<xsl:when test="@attr = ''">
Attribute 'attr' is default
</xsl:when>
<xsl:otherwise>
Attribute 'attr' is <xsl:value-of select="@attr"/>
</xsl:otherwise>
<xsl:choose>
</xsl:template>


You might consider a different approach:

<xsl:template match="/root/tag">
Attribute 'attr' is <xsl:apply-templates mode="attr-default" select="."/>
</xsl:template>

<xsl:template mode="attr-default" match="*[@attr]">
<xsl:value-of select="@attr"/>
</xsl:template>

<xsl:template mode="attr-default" match="*">
<xsl:text>default</xsl:text>
</xsl:template>

Or you could use a named template containing <xsl:choose>.

-- Richard
Jul 20 '05 #3
Richard Tobin wrote:
You might consider a different approach:

<xsl:template match="/root/tag">
Attribute 'attr' is <xsl:apply-templates mode="attr-default" select="."/>
</xsl:template>

<xsl:template mode="attr-default" match="*[@attr]">
<xsl:value-of select="@attr"/>
</xsl:template>

<xsl:template mode="attr-default" match="*">
<xsl:text>default</xsl:text>
</xsl:template>

Or you could use a named template containing <xsl:choose>.


I thought about these methods, but both have the same problem as my
first suggestion. It doesn't scale well. What if I have a tag that has
10 attributes and the tag has lots of complex code.

Thanks for the suggestion anyway,

Eric

Jul 20 '05 #4
Peter Gerstbach wrote:
you are right, the scope of xsl:variable ist only the current element.
But you can place the xsl:when inside the xsl:variable

<xsl:variable name="attr">
<xsl:when test="@attr = ''">
<xsl:value-of select="'default'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@attr"/>
<xsl:otherwise>
</xsl:variable>

then it should be possible to reference to $attr afterwards in the
template. I did not tried it but I hope it works!


I haven't tried it yet, but I am sure this method works and it is
exactly what I was looking for. I haven't been a XSLT hacker very long
so I am still getting used to it's funky way of doing things. I guess it
is not much different than C-based languages having the following construct:

_attr = attr ? bar : "default";

Thanks for your help,

Eric

Jul 20 '05 #5

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

Similar topics

1
by: Wolfgang | last post by:
XSLT transformations by default seem to pass name space attributes into the root element of their output (example below). QUESTION: Is it possible to control this, i.e. not genrating a name...
1
by: Edwin G. Castro | last post by:
Is there a way to handle optional attributes in xslt? I'd like to determine if an attribute exists and do some action if it does. Otherwise, I want to take some other action or simply do...
8
by: Darren Davison | last post by:
given the following DOM snippet; <root> <sub1 foo="4">testing</sub1> <sub1 foo="0">hello</sub1> <sub1 foo="0">world</sub1> <sub1>hello again</sub1> </root> I need to transform with XSL to...
3
by: Stephan Brunner | last post by:
Hi I have created two flavors of an XSLT stylesheet to transform all attributes of an XML document to elements: They both work as expected with MSXML and XMLSPY but throw an exception ...
3
by: Alex | last post by:
I stumbled upon this while developing a custom XPathNavigator. It appears that copy action for attributes is broken in the .net framework XSLT processor. The intent was to just copy the entities...
3
by: Teksure | last post by:
Hi group, searching in the Internet I found two products for XML which incorporate a very robust debugger for XSL/XSLT, I would like you to see these products and then, give me your opinion about...
3
by: R. P. | last post by:
Subject: XSLT to transform a flat XML file into a structured text file I have an XML file that lists the PDF file segment names and titles of a larger document and looks something like this: ...
1
by: tslettebo | last post by:
Hi all. I've read Michael Kay's "XSLT" book, and used XSLT successfully as an HTML template system at our company (using basically the "fill-in-the-blanks" pattern of XSLT use: A template...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.