此问题类似于此处提到的问题how to unescape xml with xslt,但略有不同,因为我的文字来自处理指令。
我有这样的指示:
<?xm-mark data="<p>Here is the text</p>" ?>
我想输出<
未编码的数据部分。到目前为止我的尝试是:
<xsl:template match="processing-instruction('xm-mark')">
<mymark>
<xsl:value-of select="substring-before(substring-after(., 'data="'), '"')"
disable-output-escaping="yes" />
</mymark>
</xsl:template>
然而,这让我回复了<p>
的文字。如果我删除disable-output-escaping =“yes”,我会回到&lt;
(按照我的预期进行双重编码)。既然我不能在我的模板中放置一个值 - 值得知道我是如何对数据进行处理的呢?
答案 0 :(得分:3)
这是您通过将标记转换为文本来销毁标记时获得的结果。
记住永远不要“设计”这些可怕的事情。
此外,诉诸DOE是一种绝望的迹象,is not guaranteed to work (DOE不是强制性功能和一些主要的XSLT 1.0处理器,例如FF使用的处理器实施它。)
那么,还有什么其他选择?
一种可能的解决方案是编写一个扩展函数(在XSLT / XPath版本1.0和2.0中没有这样的标准函数),它接受一个字符串,将其解析为XML并返回生成的XML文档。它会像这样使用:
<xsl:copy-of select=
"xx:parse(substring-before(substring-after(., 'data="'), '"'))/*"/>
答案 1 :(得分:1)
处理说明不需要转义任何内容,它们的解析类似于评论,因为<?
和?>
之间的任何内容都完全按原样处理。如果可以的话,你需要修改生成该指令的任何内容来生成它:
<?xm-mark data="<p>Here is the text</p>" ?>
如果你不能这样做,我甚至不会尝试使用XSLT来解析它。
编辑:我应该澄清一下,因为你可能会比你需要的东西更复杂:处理指令没有属性,甚至“和末尾的空格都是'价值的一部分'处理指令节点'。你实际上得到了一个名为xm-mark
且值data="<p>Here is the text</p>"
的处理指令(包括末尾的空格,这里没有显示); {{ 1}}与data
部分一样是值的一部分。
在你的情况下<p>..</p>
可能已经足够了,那么处理指令节点的值只是<?xm-mark <p>Here is the text</p>?>
,这是你可能感兴趣的全部内容。
<p>Here is the text</p>
注意:因为 <xsl:template match="processing-instruction('xm-mark')">
<xsl:element name="mymark">
<xsl:call-template name="unescape">
<xsl:with-param name="input" select="substring-before(substring-after(., 'data="'), '"')" />
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="unescape">
<xsl:param name="input" />
<xsl:choose>
<xsl:when test="contains($input, '&lt;')">
<xsl:call-template name="unescape">
<xsl:with-param name="input" select="substring-before($input, '&lt;')" />
</xsl:call-template>
<xsl:text><</xsl:text>
<xsl:call-template name="unescape">
<xsl:with-param name="input" select="substring-after($input, '&lt;')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
被视为文本而不是标记,所以在使用xslt进行处理时,您需要使用&
来引用它。因此,如果在xml文档中“按原样”输出,则处理指令的值实际上表示为&
。上面的xsl至少会将其转换为&lt;p>etc..
,但如果您想要实际的<p>etc..
标记,请使用扩展方法。