views:

72

answers:

3

Hello

I've been looking for a method to strip my XML content of apostrophes (') since my DBMS is complaining of receiving those.

I need

<name> Jim O'Connor</name>

to become:

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

By looking at the example described here, that is supposed to replace ' with '', I constructed the following script:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
      <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>

UPDATE: it works fine

Thanks for your help

A: 

You have a couple of issues syntactically...

  1. You can't have a name attribute on an apply-templates tag.
  2. Your xpath, "node()|@*", is ambiguous.

Have you run this through a debugger? I would suggest Oxygen.

dacracot
The xpath "node()|@*" isn't ambiguous. node() is short for `child::node()` which will match any node that is a child of another node. Attributes aren't children of any other nodes, so they don't match this pattern.http://www.dpawson.co.uk/xsl/sect2/nodetest.html
DevNull
A: 

The main problem is in your last template. As dacracot points out, xsl:apply-templates does not take a name attribute. To call a named template, you'd use xsl:call-template.

If you want to apply your SQL escaping to all text nodes, you could try replacing your last template with something like this:

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

Also, why disable-output-escaping? If the text contains special characters (<, >, &), you'll get malformed XML as the output.

Jukka Matilainen
I tried using that instead of my broken template, but still no successs
azathoth
Jukka Matilainen
A: 

Is there a reason to call a separate template to do the replacement? What processor are you using? You should be able do the replacement in the match="text()" template.

This works for me using Saxon 9-HE:

Input XML:

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

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
   <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>

Output XML:

<?xml version="1.0" encoding="UTF-8"?>
<name> Jim O''Connor</name>
DevNull
this brings several errors when debugging with Oxygen: Description: Unknown nodetype: elementStart location: 5:40Description: Extra illegal tokens: 'element', '(', ')', '|', '@', '*'Start location: 5:40Description: Could not find function: replaceStart location: 12:62Description: Could not find function: dataStart location: 12:62Description: Expected ,, but found: ''Start location: 12:62
azathoth
It depends on what processor you're using in oXygen. I'm using Saxon-HE in oXygen 11 and it works fine. You're probably using Xalan as your 1.0 processor in oXygen.
DevNull
indeed. xalan is what I'm bound to
azathoth
My condolences ;-)
DevNull