Очистка входов БД с помощью XSLT - PullRequest
0 голосов
/ 13 мая 2010

Я искал метод, чтобы лишить моего содержимого XML апострофов ('), так как моя СУБД жалуется на их получение.

мне нужно

<name> Jim O'Connor</name>

стать:

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

Взглянув на описанный пример здесь , который должен заменить ' на '', я создал следующий скрипт:

    <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 голосов
/ 13 мая 2010

Основная проблема в вашем последнем шаблоне. Как указывает dacracot , xsl: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.

0 голосов
/ 14 мая 2010

Есть ли причина вызывать отдельный шаблон для замены? Какой процессор вы используете? Вы должны быть в состоянии сделать замену в шаблоне 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>
0 голосов
/ 13 мая 2010

У вас есть пара синтаксических проблем ...

  1. Вы не можете иметь атрибут имени в теге apply-templates.
  2. Ваш xpath, "node () | @ *", неоднозначен.

Вы запускали это через отладчик? Я бы предложил Кислород.

...