XSLT:用''替换单引号

时间:2011-10-10 10:45:23

标签: php xslt

我正在使用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');?>

所以我想用\'

替换所有单引号

5 个答案:

答案 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='"&apos;"' />
            <xsl:with-param name="with" select='"\&apos;"'/>
        </xsl:call-template>
        <xsl:text>');</xsl:text>
    </xsl:processing-instruction>
</xsl:template>

注意:

  1. 使用<xsl:text>明确定义用于输出的文本,而不必担心该文本和模板调用之间的空格。
  2. 使用单引号将替换参数的select语句括起来,以便使用双引号来指示包含单个引号的文本语句报价
  3. 使用实体引用&apos;作为单引号(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 );