Defaulting empty XML elements

J

Jyrki Keisala

Hi,

I have an XML file which I want to present as a HTML table, and I'm
looking for a quick way of defaulting all empty elements in my XML file
to a nbsp (using the   notation) in my XSL transformation file, so
that if I have for example an XML record of

<record>
<elem1>fii</elem1>
<elem2 />
<elem3 />
<elem4>foo</elem4>
</record>

this would get represented with my XSL transformation as

<table>
<tr>
<td>elem1</td>
<td>elem2</td>
<td>elem3</td>
<td>elem4</td>
</tr>
<tr>
<td>fii</td>
<td> </td>
<td> </td>
<td>foo</td>
</tr>
</table>

It seems a bit tedious to use the structure

<td>
<xsl:choose>
<xsl:when test="string-length(elem1) > 0">
<xsl:value-of select="elem1"/>
</xsl:when>
<xsl:eek:therwise>
 
</xsl:eek:therwise>
</xsl:choose>
</td>

for all of my XML elements in my XSL file...also, I don't want to do the
defaulting on XML side (with a DTD), since I might use the same XML data
for different purposes than just HTML tables, in which case the default
values I want might be something else than the nbsp. That is why I would
rather keep this nbsp defaulting on XSL side, so that this particular
defaulting would be related to this HTML table output format only.

BR,
Jyrki Keisala
 
K

Kenneth Stephen

this would get represented with my XSL transformation as

<table>
<tr>
<td>elem1</td>
<td>elem2</td>
<td>elem3</td>
<td>elem4</td>
</tr>
<tr>
<td>fii</td>
<td> </td>
<td> </td>
<td>foo</td>
</tr>
</table>

It seems a bit tedious to use the structure

<td>
<xsl:choose>
<xsl:when test="string-length(elem1) > 0">
<xsl:value-of select="elem1"/>
</xsl:when>
<xsl:eek:therwise>
 
</xsl:eek:therwise>
</xsl:choose>
</td>

Hi,

I agree with the other poster : XSL can get tedious. The standard
technique in programming to allow reuse (instead of code duplication) is of
course, abstraction. So you could take the code snippets you wrote and work
them into a template that is invoked as needed. For example : assuming that
<XPathA> is an XPath expression that selects all the nodes that would be
output into your table, you could write :

<xsl:template name="drawTable">
<xsl:param name="nodes" />
<xsl:param name="defaultValue" />
<xsl:for-each select="$nodes">
<td>
<xsl:choose>
<xsl:when test="string-length(elem1) > 0">
<xsl:value-of select="elem1"/>
</xsl:when>
<xsl:eek:therwise><xsl:value-of select="$defaultValue"
/></xsl:eek:therwise>
</xsl:choose>
</td>
</xsl:for-each>
</xsl:template>

...and invoke this by saying :

<xsl:call-template name="drawTable">
<xsl:with-param name="nodes" select="<XPathA>" />
<xsl:with-param name="defaultValue" select=" " />
</xsl:call-template>

This abstraction may or may not work for you. The abstraction needs to
be tuned to your application and your programming style.

Regards,
Kenneth
 
J

Jyrki Keisala

Hi,
I agree with the other poster : XSL can get tedious. The standard
technique in programming to allow reuse (instead of code duplication)
is of course, abstraction. So you could take the code snippets you
wrote and work them into a template that is invoked as needed. For
example : assuming that <XPathA> is an XPath expression that selects
all the nodes that would be output into your table, you could write :

<xsl:template name="drawTable">
<xsl:param name="nodes" />
<xsl:param name="defaultValue" />
<xsl:for-each select="$nodes">
<td>
<xsl:choose>
<xsl:when test="string-length(elem1) > 0">
<xsl:value-of select="elem1"/>
</xsl:when>
<xsl:eek:therwise><xsl:value-of select="$defaultValue"
/></xsl:eek:therwise>
</xsl:choose>
</td>
</xsl:for-each>
</xsl:template>

...and invoke this by saying :

<xsl:call-template name="drawTable">
<xsl:with-param name="nodes" select="<XPathA>" />
<xsl:with-param name="defaultValue" select=" " />
</xsl:call-template>

This abstraction may or may not work for you. The abstraction
needs to
be tuned to your application and your programming style.

Regards,
Kenneth

Hi Kenneth,

in your example template "drawTable", dis you actually mean to use

<xsl:for-each select="$nodes">
<td>
<xsl:choose>
<xsl:when test="string-length($nodes) > 0">
<xsl:value-of select="$nodes"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="$defaultValue />
</xsl:eek:therwise>
</xsl:choose>
</td>
</xsl:for-each>

so that the same "empty-string" test could be run for all empty nodes in
one for-each loop? I mean, assuming my original XML element structure,
would I then be able to use drawTable to replace all my empty elements
with this:

<xsl:call-template name="drawTable">
<xsl:with-param name="nodes" select="record/*" />
<xsl:with-param name="defaultValue" select=" " />
</xsl:call-template>

so that record/elem1, record/elem2, record/elem3, record/elem4 would all
be search-replaced against the empty string?

Regards,
Jyrki
 
K

Kenneth Stephen

Jyrki Keisala said:
Hi Kenneth,

in your example template "drawTable", dis you actually mean to use

<xsl:for-each select="$nodes">
<td>
<xsl:choose>
<xsl:when test="string-length($nodes) > 0">
<xsl:value-of select="$nodes"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="$defaultValue />
</xsl:eek:therwise>
</xsl:choose>
</td>
</xsl:for-each>

so that the same "empty-string" test could be run for all empty nodes in
one for-each loop? I mean, assuming my original XML element structure,
would I then be able to use drawTable to replace all my empty elements
with this:

<xsl:call-template name="drawTable">
<xsl:with-param name="nodes" select="record/*" />
<xsl:with-param name="defaultValue" select=" " />
</xsl:call-template>

so that record/elem1, record/elem2, record/elem3, record/elem4 would all
be search-replaced against the empty string?
Hi,

Yes, that was the intent.

Regards,
Kenneth
 

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

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top