XSLT特殊字符

时间:2010-05-28 00:53:13

标签: xml xslt

在以下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-&gttest_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:&lt;2&gt;"/>
   </Metadata>
  </TestOutput>
 </TestResult>
</Test>

5 个答案:

答案 0 :(得分:9)

简短回答:你不能。

长答案:属性的值不能包含一些特殊字符,例如'<''>''&'

如果存在,则会将其转义为:'&lt;''&gt;''&amp;'

如果输出方法是“text”,则可以生成这些字符,而不是你的情况。

也可以制作在浏览器中显示时看起来像这些字符的文字:使用:'&lt;''&gt;''&amp;'

最后,您可以使用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> &lt; &amp; &gt;</t>
 </xsl:template>
</xsl:stylesheet>

当对任何XML文档(未使用)应用此转换时,结果为:

<t><![CDATA[ < & >]]></t>

答案 1 :(得分:1)

如果&gt;出现在您的属性中是个问题,那么问题在于如何使用XML,而不是如何生成XML。

任何XML解析器在用于检索属性值时都会转义转义的字符实体。如果在使用XML文档时使用XML解析器,您将永远不会看到这一点;解析器会告诉您属性的值为display.methods::close->test_ManyInvoke

我觉得这个“问题”只出现在以下两个原因之一:

  1. 不理解XML如何工作的人正在查看输出并说“嘿,它不应该这样做。”

  2. 不了解XML如何工作的人编写了自己的逻辑来解析XML。 (“当我可以编写一个简单的正则表达式时,为什么我应该使用其他人的XML解析器?”嗯,这就是原因之一。)

  3. 作为一般的经验法则,如果您发现自己在XSLT中使用disable-output-escaping='yes'或创建CDATA部分,那么您可能做错了。这不是某些 - 两者都有适当的用途 - 但根据我的经验,绝大多数时间如果答案是“使用CDATA”你会问错误的问题。

答案 2 :(得分:1)

这是一个非常古老的问题,其他评论者可能会质疑你为什么需要这个,但如果你只是想知道如何添加&lt;或者&gt;在这里输入你的输出。

<xsl:value-of disable-output-escaping="yes" select="string('&lt;')"/>

MSDN site的更多信息。

答案 3 :(得分:0)

如果您试图逃避字符串文字中的&符号以外的任何内容,请小心。例如,

test="$some_variable = 'Wendy&apos;s'"

无效。您必须在转义字符串中转义第一个&符号,因此您需要使用

test="$some_variable = 'Wendy&amp;apos;s'

答案 4 :(得分:0)

毫无疑问,如果有人需要括号的输出。我使用 XSLT 生成纯文本并且非常确定我需要输出什么,但 XslCompiledTransform class 只是出于任何原因对其进行编码。

作为 GMK 答案的简短替代方案,我想出了:

<xsl:text disable-output-escaping="yes">&lt; ... &gt;</xsl:text>

MSDN site

上下文示例:

<xsl:template match="data">
        /// <xsl:text disable-output-escaping="yes">&lt;summary&gt;</xsl:text>
        ///     <xsl:value-of select="value"/>
        /// <xsl:text disable-output-escaping="yes">&lt;/summary&gt;</xsl:text>
        public static <xsl:text disable-output-escaping="yes">Func&lt;string&gt; </xsl:text><xsl:value-of select="@name"/>
        <xsl:text disable-output-escaping="yes"> =&gt; () =&gt;</xsl:text> I18n.<xsl:value-of select="@name"/>;
</xsl:template>

这部分为 C# 资源文件生成类似这样的内容。

        /// <summary>
        ///     Abbrechen
        /// </summary>
        public static Func<string> Abort => () => I18n.Abort;