Microsoft KB Archive/251145

= PRB: XML/XSL Render Tags as Empty-Element Tag When an Attribute Is Added with No Content =

Article ID: 251145

Article Last Modified on 5/11/2006

-

APPLIES TO


 * Microsoft XML Parser 2.0
 * Microsoft XML Parser 2.5
 * Microsoft XML Parser 2.6
 * Microsoft XML Core Services 4.0
 * Microsoft XML Core Services 4.0

-



This article was previously published under Q251145



SYMPTOMS
When you use XSL to add an attribute without any content between the start tag and the end tag, the Microsoft XML parser, MSXML, will render it as empty-element tag.



CAUSE
MSXML is trying to generate well-formed HTML without knowledge of HTML's requirement that some elements need end tags and some don't. MSXML performs heuristics that try to evaluate whether there was an attempt to add content to the tag, and if so it produces separate start and end tags. This works reasonably well, but it can be thrown off by the use of  when creating empty HTML elements that require end tags.

The XSLT Recommendation (see "References" section) addresses this problem by allowing stylesheets to output legal HTML. The XHTML Candidate Recommendation addresses this problem by promoting HTML parsers to recognized well-formed markup.



RESOLUTION
Adding an empty CDATA tag in between the start tag and the end tag immediately after the attributes will resolve the problem.



STATUS
This behavior is by design.



Steps Showing the Problem and the Workaround
  Create Test.xml like the following:     Create Test.xsl like the following:    <body onLoad="ShowProblem"> <xsl:comment><![CDATA[ function ShowProblem {        d1.innerHTML += "Content of the d1"; alert('The innerHTML of the Div (d1) is now:" ' + d1.innerHTML + '"'); }    ] ]></xsl:comment> <xsl:apply-templates select="Data/Tag1" /> <xsl:apply-templates select="Data/Tag2" /> The innerHTML of the Div (d1) show be just "Content of the d1". But instead it's now including the p tag. </xsl:template>

<xsl:template match="Tag1"> <xsl:attribute name="style">background-color: <xsl:value-of/>; </xsl:attribute> </xsl:template>

<xsl:template match="Tag2"> <xsl:value-of /> </xsl:template>

</xsl:stylesheet> </li> Navigate to Test.xml using Internet Explorer. You will see an alert box showing the innerHTML of the Div tag. You will see it includes the content of the paragraph following the Div.</li> To work around the problem, you can add an empty CDATA immediately after the ending tag of the attribute. (NOTE: When pasting this example, be sure to eliminate any extraneous white space that may appear in the formatting of the article, as this may affect the appearance of your transformed document.)</li>  Create Fix.xsl with the following code: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <body onLoad="ShowProblem"> <xsl:comment><![CDATA[ function ShowProblem {        d1.innerHTML += "Content of the d1"; alert('The innerHTML of the Div (d1) is now:" ' + d1.innerHTML + '"'); }    ] ]></xsl:comment> <xsl:apply-templates select="Data/Tag1" /> <xsl:apply-templates select="Data/Tag2" /> With the CDATA tag, the innerHTML of the Div (d1) now show up correctly. </xsl:template>

<xsl:template match="Tag1"> <xsl:attribute name="style">background-color: <xsl:value-of/>; </xsl:attribute> <![CDATA[ ] ]> </xsl:template>

<xsl:template match="Tag2"> <xsl:value-of /> </xsl:template>

</xsl:stylesheet> </li> Alter Test.xml to point to Fix.xsl.</li> Navigate to Test.xml again to show the workaround. Now the alert box will show the correct content of the Div.</li></ol>

<div class="references_section">