我正在使用 xslt 将 xml 文件转换为 html。.net xslt 引擎不断为我提供空标签的自闭合标签。
例子:
<div class="test"></div>
变成
<div class="test" />
前者是合法的 html,而后者是非法的 html,渲染效果不好。我的问题是:如何告诉 xslt 引擎 (XslCompiledTransform) 不使用自闭合标签。
如果不可能,我如何告诉我的浏览器(在这种情况下为 IE6+)正确解释自闭标签。
我正在使用 xslt 将 xml 文件转换为 html。.net xslt 引擎不断为我提供空标签的自闭合标签。
例子:
<div class="test"></div>
变成
<div class="test" />
前者是合法的 html,而后者是非法的 html,渲染效果不好。我的问题是:如何告诉 xslt 引擎 (XslCompiledTransform) 不使用自闭合标签。
如果不可能,我如何告诉我的浏览器(在这种情况下为 IE6+)正确解释自闭标签。
将您的xsl:output
方法更改为html
(而不是xml
)。
或者如果您还没有该元素,请添加它
<xsl:output method="html"/>
一种解决方法是插入一个注释元素来强制生成非自闭:
<script type="text/javascript" src="nowhere.js">
<xsl:comment></xsl:comment>
</script>
这不是一个很好的解决方案,但它有效:-)
/斯坦
如果您使用 XmlWriter 作为输出流,请改用 HTMLTextWriter。XMLWriter 会将您的 HTML 输出重新格式化回 XML。
这与 XslCompiledTransform 类有关
这是一种解决方法:
对我来说,这是脚本标签中的一个问题。我通过用分号(;)填充它来解决它
<script type="text/javascript" src="somewhere.js">;</script>
你不能告诉你的浏览器将无效的 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>
看
等等
我曾经在里面放一个<xsl:text>
元素,比如:
<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script>
您需要注意以下几点:
这是一段工作代码:
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());
我发现的简单方法是创建一个新的 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();
}
}
刚刚在 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" />
每当我希望防止元素自动关闭时,我都会使用以下内容:
<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/
不要在家里尝试这个:
<xsl:when test="self::* and not(text())">
<xsl:value-of select="concat('<', name(), '>', '</', name(), '>')" disable-output-escaping="yes"/>
</xsl:when>