XSLT自关闭标签问题

时间:2009-05-20 12:55:44

标签: .net xslt tags xslcompiledtransform

我正在使用xslt将xml文件转换为html。 .net xslt引擎为我提供空标签的自动关闭标签。

示例:

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

成为

<div class="test" />

前者是有​​效的html,而后者是非法的HTML并且呈现得很糟糕。 我的问题是: 如何告诉xslt引擎(XslCompiledTransform)不使用自闭标签。

如果不可能,我怎么能告诉我的浏览器(在这种情况下是IE6 +)正确解释自闭标签。

12 个答案:

答案 0 :(得分:23)

将您的xsl:output方法更改为html(而不是xml)。

如果您还没有元素

,请添加它
<xsl:output method="html"/>

答案 1 :(得分:15)

解决方法可以是插入注释元素以强制生成非自我关闭:

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

这不是一个漂亮的解决方案,但它有效: - )

/斯登

答案 2 :(得分:11)

如果您使用XmlWriter作为输出流,请改用HTMLTextWriter。 XMLWriter会将您的HTML输出重新格式化为XML。

答案 3 :(得分:4)

答案 4 :(得分:3)

对我而言,这是脚本标记中的一个问题。我用分号(;

填充它来解决它
<script type="text/javascript" src="somewhere.js">;</script>

答案 5 :(得分:2)

我曾经在里面放了一个<xsl:text>元素,比如:

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

答案 6 :(得分:2)

您不能告诉您的浏览器将无效的HTML处理为HTML - 您很幸运它完全理解格式错误的HTML。 :)

在样式表中一定要这样做:

<xsl:output method="html"/>

但是,如果您的源文档具有命名空间,那么这将无法解决问题。如果输出中存在名称空间节点,XSLT处理器似乎会默默地将输出方法更改回XML。

您需要将<xsl:copy-of><xsl:copy>的所有实例替换为仅使用本地名称的元素创建,例如

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

答案 7 :(得分:1)

您需要注意以下几点:

  1. 在xsl中使用 &LT; xsl:output method ='html'&gt;
  2. 在输出XmlWriter
  3. 中设置OutputSettings
  4. 在xsl里面的Html中,不要设置属性 在像这样的html标签中&lt; html xmlns =“http://www.w3.org/1999/xhtml”&gt; 但使用&lt; HTML&GT;代替。
  5. 这是一段工作代码:

    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());
    

答案 8 :(得分:0)

我发现的简单方法是创建一个新的XmlTextWriter类来覆盖WriteEndElement方法,强制非关闭标记并将序列化过程作为参数传递。

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

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}

答案 9 :(得分:0)

不要在家尝试:

<xsl:when test="self::* and not(text())">
    <xsl:value-of select="concat('&lt;', name(), '&gt;', '&lt;/', name(), '&gt;')" disable-output-escaping="yes"/>
</xsl:when>

答案 10 :(得分:0)

使用output / @ method = html在PHP 5的XSL中遇到了同样的问题。似乎分配空值属性将导致元素输出为无效的非自闭,非闭合标记:

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

结果:

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

一种可能的解决方案是有条件地添加属性:

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

导致:

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

答案 11 :(得分:0)

每当我希望阻止元素自动关闭时,我都会使用以下内容:

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

这使得渲染引擎相信元素内部存在内容,因此阻止了自我封闭。

这有点难看,所以我建议将其包含在描述性模板中并每次调用它:

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


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

然后将呈现以下内容:

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

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