在以下XSL转换中,如何输出'<'和'>'符号
输入XML:
<TestResult bugnumber="3214" testname="display.methods::close->test_ManyInvoke" errortype="Failure"><ErrorMessage><![CDATA[calling close() method failed - expected:<2>]]></ErrorMessage>
XSLT:
<xsl:template match="TestResult">
<xsl:variable name="errorMessage">
<xsl:value-of select="ErrorMessage" disable-output-escaping="yes"/>
</xsl:variable>
<Test name='{@testname}'>
<TestResult>
<Passed>false</Passed>
<State>failure</State>
<Metadata>
<Entry name='bugnumber' value='{@bugnumber}' />
</Metadata>
<TestOutput>
<Metadata>
<Entry name='ErrorMessage' value='{$errorMessage}' />
</Metadata>
</TestOutput>
</TestResult>
</Test>
</xsl:template>
输出XML:
<Test name="display.methods::close->test_ManyInvoke">
<TestResult>
<Passed>false</Passed>
<State>failure</State>
<Metadata>
<Entry name="bugnumber" value="3214"/>
</Metadata>
<TestOutput>
<Metadata>
<Entry name="ErrorMessage" value="calling close() method failed - expected:<2>"/>
</Metadata>
</TestOutput>
</TestResult>
</Test>
答案 0 :(得分:9)
简短回答:你不能。
长答案:属性的值不能包含一些特殊字符,例如'<'
,'>'
和'&'
。
如果存在,则会将其转义为:'<'
,'>'
和'&'
。
如果输出方法是“text”,则可以生成这些字符,而不是你的情况。
也可以制作在浏览器中显示时看起来像这些字符的文字:使用:'<'
,'>'
和'&'
。
最后,您可以使用CDATA部分将这些字符作为文本节点的一部分生成。以下示例说明了这一点:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output cdata-section-elements="t"
omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<t> < & ></t>
</xsl:template>
</xsl:stylesheet>
当对任何XML文档(未使用)应用此转换时,结果为:
<t><![CDATA[ < & >]]></t>
答案 1 :(得分:1)
如果>
出现在您的属性中是个问题,那么问题在于如何使用XML,而不是如何生成XML。
任何XML解析器在用于检索属性值时都会转义转义的字符实体。如果在使用XML文档时使用XML解析器,您将永远不会看到这一点;解析器会告诉您属性的值为display.methods::close->test_ManyInvoke
。
我觉得这个“问题”只出现在以下两个原因之一:
不理解XML如何工作的人正在查看输出并说“嘿,它不应该这样做。”
不了解XML如何工作的人编写了自己的逻辑来解析XML。 (“当我可以编写一个简单的正则表达式时,为什么我应该使用其他人的XML解析器?”嗯,这就是原因之一。)
作为一般的经验法则,如果您发现自己在XSLT中使用disable-output-escaping='yes'
或创建CDATA部分,那么您可能做错了。这不是某些 - 两者都有适当的用途 - 但根据我的经验,绝大多数时间如果答案是“使用CDATA”你会问错误的问题。
答案 2 :(得分:1)
这是一个非常古老的问题,其他评论者可能会质疑你为什么需要这个,但如果你只是想知道如何添加&lt;或者&gt;在这里输入你的输出。
<xsl:value-of disable-output-escaping="yes" select="string('<')"/>
MSDN site的更多信息。
答案 3 :(得分:0)
如果您试图逃避字符串文字中的&符号以外的任何内容,请小心。例如,
test="$some_variable = 'Wendy's'"
无效。您必须在转义字符串中转义第一个&符号,因此您需要使用
test="$some_variable = 'Wendy&apos;s'
答案 4 :(得分:0)
毫无疑问,如果有人需要括号的输出。我使用 XSLT 生成纯文本并且非常确定我需要输出什么,但 XslCompiledTransform class 只是出于任何原因对其进行编码。
作为 GMK 答案的简短替代方案,我想出了:
<xsl:text disable-output-escaping="yes">< ... ></xsl:text>
上下文示例:
<xsl:template match="data">
/// <xsl:text disable-output-escaping="yes"><summary></xsl:text>
/// <xsl:value-of select="value"/>
/// <xsl:text disable-output-escaping="yes"></summary></xsl:text>
public static <xsl:text disable-output-escaping="yes">Func<string> </xsl:text><xsl:value-of select="@name"/>
<xsl:text disable-output-escaping="yes"> => () =></xsl:text> I18n.<xsl:value-of select="@name"/>;
</xsl:template>
这部分为 C# 资源文件生成类似这样的内容。
/// <summary>
/// Abbrechen
/// </summary>
public static Func<string> Abort => () => I18n.Abort;