假设我有一个非常简单的XML,其空标记为“B”:
<Root>
<A>foo</A>
<B></B>
<C>bar</C>
</Root>
我目前正在使用XSLT删除一些标签,例如“C”:
<?xml version="1.0" ?>
<xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="C" />
</xsl:stylesheet>
到目前为止确定,但问题是我最终得到这样的输出:
<Root>
<A>foo</A>
<B/>
</Root>
当我真正想要的时候:
<Root>
<A>foo</A>
<B></B>
</Root>
有没有办法防止'B'崩溃?
感谢。
答案 0 :(得分:9)
好的,所以这里对我有用:
<xsl:output method="html">
答案 1 :(得分:3)
试试这个:
<script type="..." src="..."> </script>
您的HTML输出将是:
<script type="..." src="..."> </script>
 
可防止折叠,但会转换为空格。它过去对我有用。
答案 2 :(得分:2)
没有标准的方法,因为它们是等价的;您可能能够找到具有此行为选项的XSLT引擎,但我不知道。
如果您将此传递给使用此语法无法接受空标记的第三方,则您可能必须自己对输出进行后处理(或说服第三方修复其XML解析)
答案 3 :(得分:2)
决定如何呈现XML标记由XSLT引擎决定,因为解析器应该看到两个变体之间没有区别。但是,在输出HTML时,这是一个常见问题(例如,对于<textarea>
和<script>
标记。)最简单(但很难看)的解决方案是在标记内添加一个空格(这确实会改变含义)虽然标签略有。)
答案 4 :(得分:1)
这是一个很长时间的问题,我终于使用一个简单的解决方案。 添加&lt; xsl:text /&gt;如果你有空格字符。我在帮助器类中添加了一个空格。 &LT; XSL:选择&GT; &lt; xsl:when test =“$ textAreaValue =''”&gt; &LT; XSL:文本/&GT; &LT; / XSL:当&GT; &LT; XSL:否则&GT; &lt; xsl:value-of select =“$ textAreaValue”/&gt; &LT; / XSL:否则&GT; &LT; / XSL:选择&GT;
答案 5 :(得分:1)
它们并不总是等同的。许多浏览器无法处理&lt; script type =“...”src =“...”/&gt;并想要一个单独的结束标记。我在使用PHP的xml / xsl时遇到了这个问题。输出“html”不起作用,我仍在寻找解决方案。
答案 6 :(得分:1)
还应该有另一种方法(仅限XSLT2?):“xhtml”(see another thread)。 这可以防止您的代码崩溃,也不会从&lt; meta&gt;等
元素中删除结束标记答案 7 :(得分:0)
没有。 2在语法上是相同的,所以你不必担心
答案 8 :(得分:0)
如果是或 ,那应该不是问题。但是,如果您使用的另一个工具只需要 方式的空XML标记,那么您就会遇到问题。一个不太优雅的方法是通过XSLT代码在凝视和结束'B'标签之间添加一个空格。
答案 9 :(得分:0)
<xsl:text disable-output-escaping="yes">
<![CDATA[<div></div>]]>
</xsl:text>
这适用于C#的XslCompiledTransform
类与.Net 2.0,但几乎可能在其他任何地方失败。除非您自己以编程方式执行transofrm,否则请勿使用;它完全不便携。
答案 10 :(得分:0)
已经晚了7年,但对于未来的读者,我将在这里逆势而上,提出原始问题的实际解决方案。不使用空格或输出指令修改原始文件的解决方案。
这个想法是使用一个空变量来欺骗解析器。
如果您只想为一个标签B执行此操作,我首先想到的是使用类似的东西来附加虚拟变量。
<xsl:variable name="dummyempty" select="''"/>
<xsl:template match="B">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:value-of select="concat(., $dummyempty)"/>
</xsl:copy>
</xsl:template>
但我发现事实上,即使是虚拟变量也不是必需的。这保留了空标记,至少在linux中使用xsltproc
进行测试时:
<xsl:template match="B">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
要获得处理所有空标记的更通用的解决方案,请尝试以下方法:
<xsl:variable name="dummyempty" select="''"/>
<xsl:template match="*[. = '']">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
<xsl:value-of select="$dummyempty"/>
</xsl:copy>
</xsl:template>
同样,根据解析器的智能程度,您甚至可能不需要虚拟变量。