XSLT self-closing tags issue

好久不见. 提交于 2019-11-28 06:50:45

If you are using XmlWriter as your ouput stream, use HTMLTextWriter instead. XMLWriter will reformat your HTML output back to XML.

Change your xsl:output method to be html (instead of xml).

Or add it if you haven't already got the element

<xsl:output method="html"/>

A workaround can be to insert a comment element to force generation of non self closing:

<script type="text/javascript" src="nowhere.js">
<xsl:comment></xsl:comment>
</script>

It is not a pretty soloution, but it works :-)

/Sten

For me it was a problem in the script tag. I solved it by filling it with a semicolon (;)

<script type="text/javascript" src="somewhere.js">;</script>

You can't tell your browser to handle invalid HTML as HTML -- you're lucky it understands malformed HTML at all. :)

Definitely do this in your stylesheet:

<xsl:output method="html"/>

But, if your source document has namespaces, this won't do the trick. XSLT processors seem to silently change the output method back to XML if namespace nodes are present in the output.

You need to replace all instances of <xsl:copy-of> and <xsl:copy> with creations of elements with just the local name, e.g.

<xsl:template match="*">
   <xsl:element name="{local-name()}">
     <xsl:apply-templates/>
   </xsl:element>
</xsl:template>

See

etc.

I used to put an <xsl:text> element inside, like:

<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script>

There are a few things you need to be careful:

  1. In your xsl use < xsl:output method='html'>
  2. set OutputSettings in your output XmlWriter
  3. in the Html inside your xsl, don't set attributes in html tag like this < html xmlns="http://www.w3.org/1999/xhtml"> but use < html> instead.

This is a piece of working code:

string xmlStr = "<?xml version='1.0' encoding='UTF-8'?><Data></Data>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlStr);
string xslContents = @"
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  
xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl'>
<xsl:output method='html' version='4.0' omit-xml-declaration='yes' indent='yes'/>
<xsl:template match='Data'>
<html>
<body>
    <div></div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>";
XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load(XmlReader.Create(new StringReader(xslContents)));
StringWriter result = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(result, xsl.OutputSettings))
{
    xsl.Transform(doc, null, writer);
}
System.Diagnostics.Debug.Write( result.ToString());

Just experienced the same issue with PHP 5's XSL, with output/@method=html. Seems that assigning an empty value attribute will cause elements to be output as invalid non-self-closing, non-closed tags:

<input type="text" name="foo" value="{my-empty-value}" />

results in:

<input type="text" name="foo" value="">

One possible solution is to conditionally add the attribute:

<xsl:if test="string-length(my-empty-value) > 0">
    <xsl:attribute name="value">
        <xsl:value-of select="my-empty-value" />
    </xsl:attribute>
</xsl:if>

resulting in:

<input type="text" name="foo" />

I use the following whenever I wish to prevent an element from self-closing:

<xsl:value-of select="''" />

This fools the rendering engine into believe there is content inside the element, and therefore prevents self-closure.

It's a bit of an ugly fix so I recommend containing it in a descriptive template and calling that each time instead:

<xsl:template name="PreventSelfClosure">
   <xsl:value-of select="''" />
</xsl:template>


<div class="test">
   <xsl:call-template name="PreventSelfClosure"/>
</div>

This will then render the following:

<div class="test"></div>

http://curtistimson.co.uk/post/xslt/how-to-prevent-self-closing-elements-in-xslt/

The easy way I found was creating a new XmlTextWriter class to override the method WriteEndElement, forcing the non-closing tag and pass on the serialization process as parameter.

public class MyXmlTextWriter : XmlTextWriter
{
    public MyXmlTextWriter(Stream stream) : base(stream, Encoding.UTF8)
    { }
    public MyXmlTextWriter(TextWriter stream) : base(stream)
    { }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!