我正在使用XSLT将XML转换为html / php文件。在这个XSLT中,我用php代码替换了一些标签,现在我必须将属性值传递给php代码。我现在的问题是我必须使用反斜杠转义单引号才能使其正常工作。这是否可以使用XSLT。
示例:
<xsl:template match="foo">
<xsl:processing-instruction name="php">$this->doSomething('<xsl:value-of select="./@bar" />');</xsl:processing-instruction>
</xsl:template>
如果我现在有一个模板:
<foo bar="test'xyz"/>
这会产生:
<?php $this->doSomething('test'xyz');?>
我现在想要实现的目标如下:
<?php $this->doSomething('test\'xyz');?>
所以我想用\'
替换所有单引号答案 0 :(得分:6)
使用recursive template进行查找/替换:
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text"
select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="with" select="$with"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
应用于您的示例:
<xsl:template match="foo">
<xsl:processing-instruction name="php">
<xsl:text>$this->doSomething('</xsl:text>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="./@bar"/>
<xsl:with-param name="replace" select='"'"' />
<xsl:with-param name="with" select='"\'"'/>
</xsl:call-template>
<xsl:text>');</xsl:text>
</xsl:processing-instruction>
</xsl:template>
注意:强>
<xsl:text>
明确定义用于输出的文本,而不必担心该文本和模板调用之间的空格。'
作为单引号(a.k.a.撇号)答案 1 :(得分:2)
为什么不使用标准的XSLT 2.0替换功能?或者XSLT 1.0替换实现xslt 1.0 string replace function
答案 2 :(得分:2)
对于XSLT 1.0解决方案,您可以编写自己的递归解决方案,也可以使用FXSL模板str-map
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:testmap="testmap" xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="xsl f testmap"
>
<xsl:import href="str-dvc-map.xsl"/>
<testmap:testmap/>
<xsl:variable name="vTarget">'</xsl:variable>
<xsl:variable name="vReplacement">\</xsl:variable>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>
<xsl:call-template name="str-map">
<xsl:with-param name="pFun" select="$vTestMap"/>
<xsl:with-param name="pStr" select="string(/*/@bar)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="escapeApos" mode="f:FXSL"
match="*[namespace-uri() = 'testmap']">
<xsl:param name="arg1"/>
<xsl:if test="$arg1 = $vTarget">
<xsl:value-of select="$vReplacement"/>
</xsl:if>
<xsl:value-of select="$arg1"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<foo bar="test'xyz"/>
产生了想要的正确结果:
test\'xyz
答案 3 :(得分:1)
这是一种更简单,不优雅但更快的替换单引号的方法:
<xsl:variable name="single_quote"><xsl:text>'</xsl:text></xsl:variable>
<xsl:variable name="temp_filename" select="replace($temp_filename,$single_quote,'')"/>
1)定义一个只包含撇号的变量。 xsl:text是获取xsl来处理&#39;作为一个简单的角色
2)使用替换函数使用该变量作为匹配的字符串。在这个例子中,我只是删除它。
答案 4 :(得分:-1)
只需使用:
$string = str_replace( "'", "\\'", $string );