使用XSLT清理数据库输入

时间:2010-05-13 15:02:46

标签: sql xslt input sanitize apostrophe

我一直在寻找一种方法来剥离我的撇号(')的XML内容,因为我的DBMS抱怨收到这些内容。

我需要

<name> Jim O'Connor</name>

成为:

<name> Jim O''Connor</name>

通过查看here描述的示例,该示例应该用'替换'',我构建了以下脚本:

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

      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
      </xsl:template>

      <xsl:template name="sqlApostrophe">
        <xsl:param name="string" />
        <xsl:variable name="apostrophe">'</xsl:variable>
        <xsl:choose>
          <xsl:when test="contains($string,$apostrophe)">
            <xsl:value-of select="concat(substring-before($string,$apostrophe), $apostrophe,$apostrophe)"
            disable-output-escaping="yes" />
            <xsl:call-template name="sqlApostrophe">
              <xsl:with-param name="string"
              select="substring-after($string,$apostrophe)" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$string"
            disable-output-escaping="yes" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>

      <xsl:template match="text()">
        <xsl:call-template name="sqlApostrophe">
          <xsl:with-param name="string" select="."/>
        </xsl:call-template>
      </xsl:template>

    </xsl:stylesheet>

更新:工作正常

感谢您的帮助

3 个答案:

答案 0 :(得分:0)

你在语法上有几个问题......

  1. 您不能在apply-templates标记上拥有name属性。
  2. 您的xpath,“node()| @ *”,不明确。
  3. 您是通过调试器运行的吗?我会建议氧气。

答案 1 :(得分:0)

主要问题出在您的上一个模板中。由于dacracot points outxsl:apply-templates不会采用name属性。要调用命名模板,请使用xsl:call-template

如果要将SQL转义应用于所有文本节点,可以尝试使用以下内容替换上一个模板:

<xsl:template match="text()">
  <xsl:call-template name="sqlApostrophe">
    <xsl:with-param name="string" select="."/>
  </xsl:call-template>
</xsl:template>

另外,为什么disable-output-escaping?如果文本包含特殊字符(<>&),那么您将获得格式错误的XML作为输出。

答案 2 :(得分:0)

是否有理由调用单独的模板进行替换?你在用什么处理器?您应该可以在match="text()"模板中进行替换。

这对我使用Saxon 9-HE:

输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<name> Jim O'Connor</name>

<强>样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output indent="yes"/>

   <xsl:template match="element()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>

    <xsl:template match="text()">
        <xsl:value-of select="replace(data(.),'''','''''')"/>
    </xsl:template>

</xsl:stylesheet>

输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<name> Jim O''Connor</name>