The ABCs of XML, Part 4

This article provides more of what you need to know to survive in the world of connected data by identifying a few common problems you are likely to encounter transforming XML into other formats.

By John T. Sever

Share Print Related RSS
Page 2 of 3 1 | 2 | 3 View on one page

<RecipeElement xmlns=”urn:Rockwell/
 MasterRecipe”>
 <OtherElements/>
</RecipeElement>

In this sample, the namespace is assigned the explicit prefix rs and therefore is no longer the default namespace.  Because no default namespace is declared, and because RecipeElement does not use the rs prefix, it belongs to the default null namespace and may be matched as RecipeElement and OtherElements respectively.

<RecipeElement xmlns:rs=”urn:Rockwell/
 MasterRecipe”>
<OtherElements/>
</RecipeElement>

In this sample, the namespace is assigned a prefix which is not used by RecipeElement. Therefore, matching this element requires a namespace declaration with a prefix in your stylesheet. Although it may be confusing, the XSLT stylesheet prefix is not required to match the XML source document prefix because a prefix is only a shorthand local alias of the full namespace. However, I recommend using the identical prefixes in your transforms to avoid confusion.

You may be surprised to learn that OtherElements is included in the default null namespace! Only default namespaces are inherited by child nodes. The prefixed namespace used in this sample is not the default namespace, and therefore is not inherited by OtherElements. This means that RecipeElement and OtherElements are members of different namespaces.

 

Character Entity Escape Sequences

 

Character

Sequence

&quot;

TAB

&#09;

New Line

&#10;

&

&amp;

<

&lt;

>

&gt;

&apos;

    

The most commonly used character entities and their escape sequences are shown here.

<rs:RecipeElement xmlns:rs=”urn:Rockwell/
 MasterRecipe”>
<OtherElements/>
</rs:RecipeElement>

I used the top of an RSBatch master recipe for the above samples. Rockwell uses this default namespace for each recipe saved in XML format. Therefore, your transformation for any RSBatch recipe should look like this.

<xsl:stylesheet version=”1.0”  xmlns:xsl=”http://www.
  w3.org/1999/XSL/Transform”
 xmlns:rs=” urn:Rockwell/MasterRecipe”
 exclude-result-prefixes=”rs”>
 <xsl:template match=”rs:RecipeElement”>…
 </xsl:template>
</xsl:stylesheet>

XML and XSLT namespaces can be one of the most frustrating aspects of developing XSLT transforms if you don’t understand these fine points, so I suggest you reread this section and make sure you understand how default namespaces differ from prefixed namespaces. A little experimentation can help too.

Problem 3 – My stylesheet automatically adds namespace attributes to output elements. Can I remove these?
You can never produce an output file using namespace prefixes that have not been declared; therefore, each namespace used in the output must be declared at least once. However, you may find that your output is littered with namespace declarations in nearly every element, whether they are used by that element or not. To suppress unnecessary namespace declarations, use the attribute exclude-results-prefixes in the xsl:stylesheet element (see previous example).

The value of this attribute is a list of namespace prefixes separated by white space. Remember this will not remove all namespace declarations, but it will remove unused and unnecessary namespace declarations.

Problem 4 – Text Output
Generating text output such as a comma-separated-values (CSV) file can prove more difficult than you may expect until you understand how the processor handles text and white space. Often you may find it difficult to generate one particular character like a quotation mark (“) because it has specific meaning in XML or by the XSLT language. Here are a few pointers for generating plain text output.

Make sure to include the output element before your templates as follows: <xsl:output method=”text”/>.
Use concat() function when creating output that is a combination of many text nodes or a mix of text nodes and literal text. This sample will generate a single CSV row with two comma separated columns, where each value is contained within quotation marks.

<xsl:value-of select=”concat(‘&quot;’,Value1, ‘&quot;,
 &quot;’, Value2, ‘&quot;&#10;’)”/>

Use the <xsl:text> element instead of literal text in your templates. This will give you more explicit control of your output while maintaining an easy to read transform. XSLT elements are not allowed inside an <xsl:text> element. The following verbose sample will produce the same output as the previous sample.

<xsl:text>”</xsl:text><xsl:value-of select=”Value1”/>
<xsl:text>”,”</xsl:text><xsl:value-of select=”Value2”/>
<xsl:text>”&#10;</xsl:text>

Use a CDATA section to simplify using special characters because everything inside of CDATA is ignored by the XML parser. Again, this will not work if your output is to be a mixture of literal text and XSLT elements, as in the previous example. A CDATA section begins with <![CDATA[ and ends with ]]>.

Page 2 of 3 1 | 2 | 3 View on one page
Share Print Reprints Permissions

What are your comments?

You cannot post comments until you have logged in. Login Here.

Comments

No one has commented on this page yet.

RSS feed for comments on this page | RSS feed for all comments