当尝试输出空文本区域元素时,.NET XSLT 处理器会将该元素折叠为其简短形式。而不是这个:
<textarea id="blah" name="blah"></textarea>
我明白了:
<textarea id="blah" name="blah"/>
这导致许多网络浏览器(包括 IE 和 Firefox)将页面的其余部分呈现为文本区域的 contents。 这太糟糕了。
如果我在中间放置一些内容(例如不间断空格),我可以强制 XSLT 处理器输出开始和结束文本区域标记。但这意味着我必须在客户端进行更多的解析和验证,以判断文本区域何时“真正”为空。我还必须使用 JavaScript 删除多余的空格,以便用户不会以空格开始评论。
有谁知道如何强制 XSLT 处理器呈现开始和结束标记而无需插入虚拟内容?
<!-- This prevents empty textarea elements being rendered as singletons in the XHTML output by adding a newline character -->
<xsl:template name="xhtml-textarea-contents">
<!-- what should be contained in the textarea -->
<xsl:param name="contents" />
<xsl:choose>
<xsl:when test="$contents = ''"><xsl:text>
</xsl:text></xsl:when>
<xsl:otherwise><xsl:copy-of select="$contents" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
XslCompiledTransform transform = new XslCompiledTransform();
...
MemoryStream stream = new MemoryStream();
transform.Transform(reader, args, stream);
为了传递正确的设置,我必须使用接受 XmlWriter 的重载。
// using XmlWriter so I can pass the output settings along.
XmlWriter writer = XmlWriter.Create(stream, transform.OutputSettings);
transform.Transform(reader, args, writer);
微软在那里使用了一种非常奇怪的设计模式。
这是一个使用 jQuery 的示例:
<textarea> <textarea>
<script>
$(document).ready(function(){
$('textarea').each(
function(index){$(this).text('');}
);
});
</script>
<xsl:output method="xml">
和
<xsl:output method="xhtml">
中都可以重现(我假设
method="html"
不适用于我们的场景,即输出必须是格式良好的 xml)为了避免文本区域标签崩溃,我们必须在其中插入一些内容,但我们也必须避免篡改
实际内容。以下:
<xsl:if test="not(normalize-space())"><xsl:comment></xsl:comment></xsl:if>
产生正确的结果(即防止空的
textarea
自动关闭并且不引入人为内容)。我相信规范中在后模式验证信息集的节点构造下提到了这种行为,其中空注释的字符串值将变成零长度字符串;然而,该文档的措辞对于轻松的下午阅读来说太w3-ey了。 进一步推动它(
所以如果它不篡改内容,我们真的需要xsl:if
吗?),这是防止某些标签崩溃的最终模板(我渴望遵循身份转换图案):
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="textarea">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:comment></xsl:comment>
</xsl:copy>
</xsl:template>
注意:浏览器的行为表明这种转换也应该应用于其他一些元素,例如段落。然而,自动关闭
<p/>
并不像自动关闭
<textarea/>
那么具有破坏性!
FileStream xmlFileStream = File.Create("file.xml");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("transform.xsl");
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlWriter xmlWriter = XmlWriter.Create(xmlFileStream, settings);
transform.Transform(sourceXml, null, xmlWriter);
<xsl:template name="fillTextArea">
<xsl:param name="sourceStr" />
<xsl:element name="textarea">
<xsl:attribute name="value">
<xsl:value-of select="$sourceStr"></xsl:value-of>
</xsl:attribute>
<xsl:attribute name="class">notes</xsl:attribute>
</xsl:element>
</xsl:template>
<textarea><xsl:text>
</xsl:text></textarea>
或:
<textarea><xsl:text><![CDATA[]]></xsl:text></textarea>