2010-05-13 7 views
0

Je cherchais une méthode pour supprimer mon contenu XML d'apostrophes (') car mon SGBD se plaint de les recevoir.Désinfection des entrées DB avec XSLT

J'ai besoin

<name> Jim O'Connor</name> 

devenir:

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

En regardant l'exemple décrit here, qui est censé remplacer ' avec '', je construisais le script suivant:

<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> 

MISE À JOUR: il fonctionne très bien

Merci pour votre aide

+0

1) Quel processus et quelle langue utilisez-vous pour effectuer l'insertion de la base de données? 2) Le langage de la question 1 pourrait-il être utilisé pour pré-traiter les guillemets simples? – dacracot

+0

J'appelle une procédure stockée SQL Server, avec un tas d'expressions XPath comme paramètres – azathoth

+1

Votre procédure stockée est boguée. Vous devriez régler le problème ici, pas dans le XSLT. – Alohci

Répondre

0

Le problème principal est dans votre dernier modèle. Comme dacracot points out, xsl:apply-templates ne prend pas un attribut name. Pour appeler un modèle nommé, vous devez utiliser xsl:call-template.

Si vous souhaitez appliquer SQL échapper à tous les nœuds de texte, vous pouvez essayer de remplacer votre dernier modèle avec quelque chose comme ceci:

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

Aussi, pourquoi disable-output-escaping? Si le texte contient des caractères spéciaux (<, >, &), vous obtiendrez un résultat XML incorrect.

+0

J'ai essayé d'utiliser cela à la place de mon modèle cassé, mais toujours pas de succès – azathoth

+0

Comment ça marche? Peut-être pourriez-vous poster un exemple plus complet. Voici ce qui fonctionne pour moi. Feuille de style: http://pastebin.com/raw.php?i=vV0F2nYZ Entrée: http://pastebin.com/raw.php?i=J5wLF9B0 Résultat en direct: http://www.w3.org/2000/06 /webdata/xslt?xslfile=http%3A%2F%2Fpastebin.com%2Fdownload.php%3Fi%3DvV0F2nYZ&xmlfile=http%3A%2F%2Fpastebin.com%2Fdownload.php%3Fi%3DJ5wLF9B0&transform=Submit (Voir la source pour voir la résultat). –

0

Vous avez quelques problèmes syntaxiquement ...

  1. Vous ne pouvez pas avoir un attribut nom sur une étiquette apply-templates.
  2. Votre xpath, "node() | @ *", est ambigu.

Avez-vous exécuté cela via un débogueur? Je suggérerais l'oxygène.

+0

Le xpath "node() | @ *" n'est pas ambigu. node() est l'abréviation de 'child :: node()' qui correspond à tout noeud qui est un enfant d'un autre noeud. Les attributs ne sont pas des enfants d'autres nœuds, ils ne correspondent donc pas à ce modèle. http://www.dpawson.co.uk/xsl/sect2/nodetest.html –

0

Existe-t-il une raison d'appeler un modèle distinct pour effectuer le remplacement? Quel processeur utilisez-vous? Vous devriez être capable de faire le remplacement dans le modèle match="text()".

Cela fonctionne pour moi en utilisant Saxon 9 HE:

XML Entrée:

<?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"> 
    <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 de sortie:

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

cela apporte plusieurs erreurs lors du débogage avec l'oxygène: Description: nodetype inconnu: élément Point de départ: 05:40 Description: jetons supplémentaires illégales: 'élément', '(', ')', '|', ' @ », '*' Point de départ: 05:40 description: Impossible de trouver la fonction: remplacer emplacement de départ: 12:62 description: Impossible fonction trouver: données Point de départ: 12:62 description de : Attendu, mais trouvé: '' Lieu de départ: 12:62 – azathoth

+0

Cela dépend du processeur que vous utilisez dans oXygen. J'utilise Saxon-HE dans oXygen 11 et ça marche bien. Vous utilisez probablement Xalan comme processeur 1.0 dans oXygen. –

+0

en effet. xalan est ce que je suis lié à – azathoth