即使在转义字符后也无法让xslt输出(&)

时间:2008-09-15 23:12:12

标签: xml xslt escaping invalid-characters

我正在尝试创建由&符号分隔的变量赋值的查询字符串(例如:"var1=x&var2=y&...")。我计划将此字符串传递给嵌入式Flash文件。

我无法在XSLT中显示&符号。如果我只是键入&而没有标签,那么渲染XSLT文档就会出现问题。如果我键入&amp;并且没有标签,则文档的输出为&amp;,没有任何更改。如果我输入<xsl:value-of select="&" /><xsl:value-of select="&amp;" />,我也会收到错误消息。这可能吗?注意:我也尝试&amp;amp;但没有成功。

13 个答案:

答案 0 :(得分:17)

您可以将disable-output-escapingCDATA部分合并。试试这个:

<xsl:text disable-output-escaping="yes"><![CDATA[&]]></xsl:text>

答案 1 :(得分:12)

  

我正在尝试创建一个分离的变量赋值的查询字符串   通过&符号(例如:"var1=x&var2=y&...")。我打算通过这个   字符串到嵌入式Flash文件中。

     

我无法在XSLT中显示&符号。

以下是如何生成此类网址的可运行,简短且完整的演示:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vX" select="'x'"/>
 <xsl:variable name="vY" select="'y'"/>
 <xsl:variable name="vZ" select="'z'"/>

  <xsl:template match="/">
    <xsl:value-of select=
"concat('http://www.myUrl.com/?vA=a&amp;vX=', $vX, '&amp;vY=', $vY, '&amp;vZ=', $vZ)"/>
  </xsl:template>
</xsl:stylesheet>

将此转换应用于任何源XML文档(忽略)

<t/>

产生了想要的正确结果:

http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z

至于问题中提出的其他问题:

  

如果我键入&amp;没有标签,那么输出就是   文档为&amp;,没有任何更改。

上述陈述根本不是真的......只需运行上面的转换并查看结果。

真正发生的事情

您看到的结果绝对正确,但您的输出方法是htmlxmlmethod=的默认值),因此XSLT处理器的序列化程序必须代表正确的结果 - 字符串http://www.myUrl.com/?vA=a&vX=x&vY=y&vZ=z - 作为格式良好的XML文档或HTML树中的文本节点的一部分。

根据定义,在格式良好的XML文档中,文字符号必须通过字符引用进行转义,例如内置&amp;&#38;&#x26;

记住:表示为(部分)XML文本节点或HTML树中的字符串在表示为文本时可能看起来不像是相同的字符串。然而,这些是同一串的两种不同表示。

为了更好地理解这个简单的事实,请执行以下操作

进行上述转换并替换xsl:output声明:

 <xsl:output method="text"/>

这一个:

 <xsl:output method="xml"/>

此外,将输出包围在单个XML元素中。您也可以尝试使用不同的逃生用于&符号。转换现在可能如下所示:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" method="xml"/>

 <xsl:variable name="vX" select="'x'"/>
 <xsl:variable name="vY" select="'y'"/>
 <xsl:variable name="vZ" select="'z'"/>

  <xsl:template match="/">
        <t>
            <xsl:value-of select=
 "concat('http://www.myUrl.com/?vA=a&amp;vX=', $vX, '&#38;vY=', $vY, '&#x26;vZ=', $vZ)"/>
        </t>
  </xsl:template>
</xsl:stylesheet>

结果

<t>http://www.myUrl.com/?vA=a&amp;vX=x&amp;vY=y&amp;vZ=z</t>

输出方法html将获得相同的结果。

<强>问题

输出的URL是否与第一次转换中的输出不同(甚至&#34;损坏&#34;)?

<强>答案

不,在这两种情况下都输出了相同的字符串 - 但是在每种情况下都使用了不同的字符串表示

<强>问题

我必须使用DOE(disable-output-escaping="yes")属性才能输出想要的网址吗?

<强>答案

不,如第一次转型所示。

<强>问题

是否建议使用DOE(disable-output-escaping="yes")属性来输出想要的网址?

<强>答案

不,使用DOE在XSLT中是一种不好的做法,通常是程序员没有很好地掌握XSLT处理模型的信号。此外,DOE只是XSLT 1.0的一个可选功能,您的XSLT处理器可能无法实现DOE,或者即使这样做,您也可能无法使用其他XSLT处理器运行相同的转换。

<强>问题

  

我从一个不同的问题来到我为此付出的问题。   我的问题:我尝试生成这个onclick方法:

    <input type="submit" 
onClick="return confirm('are you sure?') && confirm('seriously?');" />
     

我能做的是:我可以将确认放在一个函数中......但是它   我不能做一个&amp;在属性里面!解决了   这个问题是我认为解决我的问题。

<强>答案

实际上,您可以在属性内的JavaScript表达式中指定&&布尔运算,方法是将其表示为&amp;&amp;

这是一个完整的示例,每个人都可以投放,就像我在三个浏览器上一样:Chrome,Firefox 41.1.01和IE11:

<强> HTML

<!DOCTYPE html> 

    <html> 
      <head> 
        <link rel="stylesheet" href="style.css"> 
        <script src="script.js"></script> 
      </head> 
      <body> 
        <h1>Hello Plunker!</h1> 
        <input type="submit" 
onClick="alert(confirm('are you sure?') &amp;&amp; confirm('seriously?'));" /> 
      </body> 
    </html>

JavaScript (script.js):

function confirm(message) { 
  alert(message); 
  return message === 'are you sure?'; 

}

运行此功能后,您首先会收到此提醒:

enter image description here

然后,点击OK按钮后,您将收到第二个提醒:

enter image description here

点击OK后,您最终会收到产生&&操作结果的提醒:

enter image description here

您可以通过更改传递给confirm()函数的参数值来使用此代码,您将验证生成的结果是否使用&&运算符。

例如,如果您将<input>元素更改为:

<input type="submit" 
onClick="alert(confirm('really sure?') &amp;&amp; confirm('seriously?'));" /> 

您将首先获得此警报:

enter image description here

当您点击OK时,您将立即获得&&操作的最终结果:

enter image description here

第二个警告被跳过,因为&&操作的第一个操作数是false,JavaScript正在快捷&&,其中第一个操作数为false

总结

通过将&&操作数指定为&&

,可以轻松地在XSLT生成的HTML文档中使用属性内的&amp;&amp;运算符

答案 2 :(得分:10)

您是在HTML或XHTML中表达URI吗?例如<tag attr="http://foo.bar/?key=value&amp;key2=value2&amp;..."/>如果是这样,“&amp;”是在属性值中表达&符号的正确方法,即使它看起来与您想要的文字URI不同。浏览器将在加载它们或将它们传递给Flash之前解码“&amp;”和任何其他字符实体引用。要嵌入文字,直接在HTML或XHTML中单独使用“&”是不正确的。

我个人也建议学习更多关于XML的知识,以便更清楚地思考这些事情。例如,尝试更多地使用W3C DOM(不仅仅是简单的Javascript);即使您不是日常使用它,学习DOM也可以帮助我正确地思考XML的树结构以及如何正确地考虑编码属性和元素。

答案 3 :(得分:6)

disable-output-escaping="yes"标记

中使用value-of

答案 4 :(得分:4)

如果您要在某个其他标记的属性(例如“embed”)中创建查询字符串作为较大网址的一部分,那么您实际上想要&amp;作为&amp; amp;逃脱虽然所有浏览器都会弄清楚你的意思和做正确的事情,如果你要将生成的文档传递给验证器,它会标记未转义的&amp;在属性值中。

答案 5 :(得分:4)

如果您尝试将XML文件作为输出生成,则需要生成&amp;(因为&,它本身就是无效的XML)。如果您只是生成一个字符串,那么您应该将样式表的输出模式设置为text,方法是将以下内容包含为xsl:stylesheet的子项

<xsl:output method="text"/>

这会阻止样式表转义,<xsl:value-of select="'&amp;'" />应该生成&

答案 6 :(得分:3)

如果您的转换正在发出XML文档,则不应禁用输出转义。您希望标记字符在输出中转义,以便您不会发出格式错误的XML。您正在使用(例如DOM)处理输出的XML对象将为您取消文本。

如果您使用字符串操作而不是XML对象来处理输出,则会出现问题。但问题不在于你的XSLT,而是决定使用字符串操作来处理XML,这几乎总是坏的。

如果您的转换正在发出HTML或文本(并且您已在<xsl:output>元素上设置输出类型,对吗?),这是一个不同的故事。然后,在disable-output-escaping='yes'元素上使用<xsl:value-of>是合适的。

但无论如何,除非你将文本包装在CDATA部分中,否则你需要转义XSLT文本节点中的标记字符。

答案 7 :(得分:1)

禁用输出转义将完成工作......因为只有文本支持此属性,您才可以操作模板,例如:

 <xsl:variable name="replaced">

    <xsl:call-template name='app'>
      <xsl:with-param name='name'/>       
    </xsl:call-template>
  </xsl:variable>


<xsl:value-of select="$replaced" disable-output-escaping="yes"/>

---&GT;在变量中包含模板调用并使用disable-output-escaping =“yes”..

答案 8 :(得分:1)

只需更换&amp;与

<![CDATA[&]]>

在数据中。 EX:数据XML

<title>Empire <![CDATA[&]]> Burlesque</title>

XSLT标签:

<xsl:value-of select="title" />

输出: 帝国与滑稽

答案 9 :(得分:0)

使用disable-output-escaping属性(布尔值)可能是实现此目的的最简单方法。请注意,您不仅可以在<xsl:value-of/>上使用此功能,还可以使用<xsl:text>,这可能更清晰,具体取决于您的具体情况。

以下是规范的相关部分:http://www.w3.org/TR/xslt#disable-output-escaping

答案 10 :(得分:0)

您应该注意,您可以在节点或字符串/文本的值中使用disable-output-escaping,如:

<xsl:value-of select="/node/here" disable-output-escaping="yes" />

<xsl:value-of select="'&amp;'" disable-output-escaping="yes" />
<xsl:text disable-output-escaping="yes">Texas A&amp;M</xsl:text>

请注意xsl:value-of。

中的单引号

但是,您无法在属性上使用disable-output-escaping。我知道它完全搞砸了,但这就是XSLT 1.0中的情况。因此以下 NOT 工作:

<xsl:value-of select="/node/here/@ttribute" disable-output-escaping="yes" />

因为在细则中是引用:

  

因此,禁用输出是 错误   逃避<xsl:value-of />或。{   用于的<xsl:text />元素   生成a的字符串值   评论,处理指令或   属性节点;

强调我的。

取自:http://www.w3.org/TR/xslt#disable-output-escaping

答案 11 :(得分:0)

org.apache.xalan.xslt.Process版本2.7.2输出到上述“这里是一个可运行的,简短而完整的演示如何生成此类URL”:

<?xml version="1.0" encoding="UTF-8"?>http://www.myUrl.com/?vA=a&amp;vX=x&amp;vY=y&amp;vZ=z11522

使用附加的omit-xml-declaration="yes"来抑制XML声明,但是使用输出method="text"来使与号转义是不合理的。

答案 12 :(得分:-3)

尝试:     &lt; xsl:value-of select =“&amp; amp;”禁用输出转义= “是”/&GT;

很抱歉,如果格式混乱了。