我试图在html文档中转义来自用户输入的引号,但是当我使用它时,replace()函数正在删除标记。为什么呢?
I.e从XSL下面的代码中,如果我改变了这一行:
<xsl:copy-of select="replace($s, '"', '\\"')" />
到
<xsl:copy-of select="$s" />
它有效,但显然没有做我需要的报价转义。或者你有任何其他方法来逃避报价。
PS:我需要转义,因为我将值传递给带有c#的后端变量,如果我没有转义它,则代码会刹车。
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template name="encode-string">
<xsl:param name="s" select="@* | node()"/>
<xsl:copy-of select="replace($s, '"', '\\"')" />
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" >
<xsl:copy-of select="Contact/node()"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
HTML
<Contact>
<MobileNumber>0123456789</MobileNumber>
<Email type="new">johndoe@coldmail.com</Email>
<Address type="red">Antartica"s drive 41</Address>
</Contact>
我需要转义所有节点的内容。也就是说,所有内容都需要被视为一个单独的字符串。类似于序列化的东西,但它也应该包括子节点属性。 (一切)
想要的结果:
<MobileNumber>0123456789</MobileNumber><Email type=\"new\">johndoe@coldmail.com</Email> <Address type=\"red\">Antartica\"s drive 41</Address>
这样我就可以将它传递给C#变量:
string content = "<MobileNumber>0123456789</MobileNumber><Email type=\"new\">johndoe@coldmail.com</Email> <Address type=\"red\">Antartica\"s drive 41</Address>";
答案 0 :(得分:0)
replace()
函数将字符串作为输入并返回一个字符串,因此它不会按照您的意图执行。
如果要全局替换字符,请考虑使用character-map ...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" use-character-maps="encode"/>
<xsl:strip-space elements="*"/>
<xsl:character-map name="encode">
<xsl:output-character character=""" string="&quot;"/>
</xsl:character-map>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
XSLT不对包含标记的词法字符串进行操作,它在节点树上运行。因此,您对replace()函数删除标记的陈述表明您还没有真正获得XSLT如何工作的正确概念模型。除非你解决这个问题,否则你会遇到更多这样的问题。
如果提供节点作为需要字符串的函数(如replace())的输入,则处理器将提取节点的字符串值,该节点是节点的所有文本节点后代的串联。您可以将其视为&#34;删除标记&#34;如果你愿意,但它并不是一个准确的描述。
解决此问题的最佳方法是将replace函数分别应用于每个后代文本节点。在XSLT 3.0中,您可以这样做:
<xsl:mode name="escape-quotes" on-no-match="shallow-copy"/>
<xsl:template match="text()" mode="escape-quotes">
<xsl:value-of select="replace(.....)"/>
</xsl:template>
然后将xsl:copy-of
替换为xsl:apply-templates
mode="escape-quotes"
。在早期的XSLT版本中,您需要拼出&#34;浅拷贝&#34;模板规则全部。
答案 2 :(得分:0)
@Martin Honnen通过此解决方案的链接提供了我在问题评论中所需的确切内容http://xsltfiddle.liberty-development.net/pPgCcot 通过在替换呼叫之前简单地使用serilize:
<xsl:template match="Contact">
<xsl:value-of select="replace(serialize(*), '"', '\\"')"/>
</xsl:template>