XSLT: How to avoid empty attributes in attribute-sets?

T

Thomas Wittek

Hi!

I'm using xsl:attribute-sets to reduce redundancy in my XSLT.
An example from a transformation to XHTML (the attribute values are
simply copied from input to output):

<xsl:attribute-set name="cellhalign">
<xsl:attribute name="align">
<xsl:value-of select="@align" />
</xsl:attribute>
<xsl:attribute name="char">
<xsl:value-of select="@char" />
</xsl:attribute>
<xsl:attribute name="charoff">
<xsl:value-of select="@charoff" />
</xsl:attribute>
</xsl:attribute-set>

Works fine, except that it generates empty attributes, if the attribute
is not defined in the source XML:

<td align="" char="" charoff="">31</td>

That's quite ugly. Especially when you have a lot of <td>'s...

Now you cannot use <xsl:if> in an <xsl:attribute-set>.
So if you like to create a "conditional attribute" you'd have to do it
within the template:

<xsl:template match="nitf:td">
<td>
<xsl:if test="@align">
<xsl:attribute name="align">
<xsl:value-of select="@align" />
</xsl:attribute>
</xsl:if>
<!-- repeat that for the other attrs -->
<xsl:apply-templates/>
</td>
</xsl:template>

But doing that will be extremely redundant if the same attributes apply
to several templates.

It there any solution to avoid redundant attribute declarations *and*
avoid empty attributes in the output XML?

Thank you very much!
Regards
 
M

Martin Honnen

Thomas said:
It there any solution to avoid redundant attribute declarations *and*
avoid empty attributes in the output XML?

As long as you simply want to copy attributes from the input to the
output you can simply do e.g.
<xsl:copy-of select="@*"/>
or for particular attributes
<xsl:copy-of select="@align | @char"/>
Doing the usual identity transformation stuff e.g.
<xsl:apply-templates select="@align | @char"/>
and
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
should also do.

Or do I misunderstand what you want to achieve?
 
T

Thomas Wittek

Martin said:
As long as you simply want to copy attributes from the input to the
output you can simply do e.g.
<xsl:copy-of select="@*"/>
or for particular attributes
<xsl:copy-of select="@align | @char"/>
Doing the usual identity transformation stuff e.g.
<xsl:apply-templates select="@align | @char"/>
and
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
should also do.

Or do I misunderstand what you want to achieve?

Thank you very much!
That perfectly solves *my* problems!

But it wouldn't work, if I'd had to rename the attributes, would it?
Fortunately, I don't have to rename them, so it works nonetheless for me.
 
M

Martin Honnen

Thomas said:
But it wouldn't work, if I'd had to rename the attributes, would it?

If you use the identity transformation approach then you can also insert
templates in the transformation process that rename attributes e.g. do
<xsl:apply-templates select="@some-attribute"/>
and
<xsl:template match="@some-attribute">
<xsl:attribute name="new-attribute">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top