Groups | Blog | Home
all groups > dotnet xml > october 2004 >

dotnet xml : XSLT transform and <foo></foo> versus <foo />


Derek Harmon
10/31/2004 6:54:24 PM
[quoted text, click to view]

There is no way to change the XSLT stylesheet to produce XML with compact
elements, because the XSLT specification purposefully leaves this an
implementation
detail. As far as XML is concerned, <OrderIDInfo></OrderIDInfo> and the
more
compact <OrderIDInfo /> are identical serializations of an XML element with
the
local name OrderIDInfo and no child nodes.

By default, the XslTransform implementation emits full end tags (probably
because
it's just simpler that way, there is less state to maintain in the processor
when it does
not need to remember the current element is empty).

Interestingly, the reason why this is a problem for you is also precisely
the answer.
XslTransform produces a resulting node tree, you can insert an XmlTextWriter
implementation that dictates how that node tree should appear in the
serialization
of the XML.

Wrap an XmlTextWriter around the output from the XslTransform's Transform( )
method and intercepting calls that XslTransform makes to the
WriteFullEndElement( )
method into calls that your custom XmlTextWriter makes to
WriteEndElement( ).
It's the WriteEndElement( ) that produces the more compact empty element (it
also maintains state about the existence of any child nodes, and so produces
a
full end tag where one is necessary).

- - - XmlTextWriterEE.cs
using System;
using System.IO;
using System.Xml;

/// <summary>
/// Wrapper that forces more compact empty element end
/// tags to be written whenever possible.
/// </summary>
public class XmlTextWriterEE : XmlTextWriter
{
public XmlTextWriterEE( TextWriter sink) : base( sink) {;}
public override void WriteFullEndElement() {
base.WriteEndElement();
}
}
- - -

This XmlTextWriter would work something like this in your application,

xslDoc.Transform( xmlDoc.CreateNavigator( ),
null, new XmlTextWriterEE( Console.Out) );


Derek Harmon

Fredrik Melin
10/31/2004 8:51:19 PM
Hi,

I have a vendor that requires me to send empty value, e.g. <OrderIDInfo />

problem is that my xslt need to add attributes, doing this

<OrderIDInfo>
<xsl:attribute name="orderID">
<xsl:value-of select="Root_Element/InvoiceHeader/Customer_PO_No" />
</xsl:attribute>
<xsl:attribute name="orderDate">
<xsl:value-of select="Root_Element/InvoiceHeader/@Date_Ordered" />
</xsl:attribute>
</OrderIDInfo>

results in <OrderIDInfo attributes..></OrderIDInfo>

Is there anyway to change so it converts to <OrderIDInfo attributes... />
Regards
Fredrik Melin

Stuart Celarier
10/31/2004 11:24:50 PM
[quoted text, click to view]

The XML specification mandates that there is no difference between an empty
element made of a start-tag followed by an end-tag
(<OrderIDInfo></OrderIDInfo>) and an empty-element tag (<OrderIDInfo/>) [1].
Every XML processor is required to treat these two cases identically, they
are merely different and equally valid serializations of an empty element.
Neither party should know or care about the difference. Anything other than
that simply isn't XML.

Your introduction of attributes on the empty element is just a red herring.
It is up to the XML serializer (not even the XSLT processor itself) how the
empty element is serialized. You will encounter the same issue if you
generate the XML with any other toolset, e.g., creating the XML in a DOM
such as System.Xml.XmlDocument, or an XmlWriter.

There is a very minor issue in the XML specification (again [1]) with
declarations of an empty element, by which is meant the DTD declaration of
an empty element such as

<!ELEMENT br EMPTY>

This is a minor issue because (1) DTDs have only extremely limited use
anymore since the emergence of XSD, and (2) the XML specification clearly
states the in the presence of an empty element definition in the DTD the
empty-element tag SHOULD be used (their emphasis), but not must be used,
i.e., either is acceptable.

Help your vendor understand the difference between the XML serialization
format and the XML InfoSet [2]. We use XML serialization only in order to
share Xml InfoSets. Best luck.

Cheers,
Stuart Celarier, Fern Creek

[1] http://www.w3.org/TR/2004/REC-xml-20040204/#sec-starttags
[2] http://www.w3.org/TR/2004/REC-xml-infoset-20040204/

AddThis Social Bookmark Button