25

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

例子:

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

变成

<div class="test" />

前者是合法的 html,而后者是非法的 html,渲染效果不好。我的问题是:如何告诉 xslt 引擎 (XslCompiledTransform) 不使用自闭合标签。

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

4

12 回答 12

24

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

或者如果您还没有该元素,请添加它

<xsl:output method="html"/>
于 2009-05-20T12:59:29.357 回答
18

一种解决方法是插入一个注释元素来强制生成非自闭:

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

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

/斯坦

于 2012-01-23T12:17:45.617 回答
11

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

于 2009-05-20T13:54:31.850 回答
4

这与 XslCompiledTransform 类有关

这是一种解决方法:

http://blogs.msdn.com/b/nareshjoshi/archive/2009/01/15/how-to-force-non-self-closing-tags-for-empty-nodes-when-using-xslcompiledtransform-class。 aspx

于 2010-09-15T15:53:21.670 回答
3

对我来说,这是脚本标签中的一个问题。我通过用分号(;)填充它来解决它

<script type="text/javascript" src="somewhere.js">;</script>
于 2010-11-24T15:22:53.717 回答
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>

等等

于 2009-05-20T13:08:45.983 回答
2

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

<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script>
于 2011-07-18T22:05:57.067 回答
1

您需要注意以下几点:

  1. 在你的 xsl 中使用 <xsl:output method='html'>
  2. 在输出 XmlWriter 中设置 OutputSettings
  3. 在您的 xsl 内的 Html 中,不要像这样在 html 标记中设置属性 < html xmlns="http://www.w3.org/1999/xhtml"> 而是使用 < html> 。

这是一段工作代码:

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());
于 2014-04-06T07:10:47.177 回答
1

我发现的简单方法是创建一个新的 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();
    }
}
于 2018-02-20T23:43:16.497 回答
0

刚刚在 PHP 5 的 XSL 中遇到了同样的问题,输出/@method=html。似乎分配一个空值属性会导致元素被输出为无效的非自闭合、非闭合标签:

<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" />
于 2012-09-24T14:57:36.287 回答
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://curtisimson.co.uk/post/xslt/how-to-prevent-self-closing-elements-in-xslt/

于 2014-07-02T15:05:55.927 回答
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>
于 2020-03-02T23:47:08.430 回答