web-dev-qa-db-fra.com

Comment échapper des caractères XML dans TSQL avant de les convertir en XML?

J'ai la structure XML qui est un paramètre d'entrée pour ma procédure stockée . Il contient un élément avec & (qui est échappé en XML). Lorsque j'extrais cet élément vers VARCHAR je reçois & qui n'est pas un caractère XML valide. Je dois y échapper, avant de reconvertir en XML. Comment faire cela sans REPLACE?

J'ai le texte suivant: param1=xyz&para2=dasdasdfdas&param3. Il fait partie de la chaîne de requête. Je l'ai converti en XML et je l'envoie dans le cadre de la structure XML:

<zzz xmlns="http://example.com">
  <aaa>aaa</aaa>
  <bbb>param1=xyz&amp;para2=dasdasdfdas&amp;param3</bbb>
</zzz>

Dans la procédure stockée, je dois l'extraire. Je fais ça avec:

ISNULL(NULLIF(LTRIM(RTRIM(@XMLInput.value('declare default element namespace "http://example.com"; (zzz/bbb)[1]', 'NVARCHAR(250)'))), ''), '');

Après cela, la valeur contient du texte normal (& - s ne sont pas échappés - &).

Après un certain traitement, je dois mettre cette chaîne dans un autre XML. Je fais:

CAST( ... AS XML);

Parce que & - s ne sont pas échappés, j'ai eu une erreur.

5
Bogdan Bogdanov

Utilisation for xml path pour créer du XML au lieu de caster.

select @YourVariable for xml path(''), type

Une chaîne vide dans l'expression du chemin et l'absence d'alias sur la colonne renvoyée vous rendra votre chaîne au format xml.

9
Mikael Eriksson

C'est du XML parfaitement valide. Si vous extrayez l'élément bbb à l'aide de .value méthode du type de données XML, elle sera désactivée à ce stade, par exemple

Results

Vous pouvez extraire et ajouter l'élément sans manipulation ni remplacement spécial, par exemple en utilisant le .modify méthode du type de données XML:

DECLARE @xml XML = '<zzz xmlns="http://example.com">
  <aaa>aaa</aaa>
  <bbb>param1=xyz&amp;para2=dasdasdfdas&amp;param3</bbb>
</zzz>'

SELECT @xml [before], DATALENGTH(@xml) dl

DECLARE @b VARCHAR(100)

;WITH XMLNAMESPACES ( DEFAULT 'http://example.com' )
SELECT @b = @xml.value('(zzz/bbb/text())[1]', 'VARCHAR(100)')

SELECT @b

SET @xml.modify('declare default element namespace "http://example.com"; insert element bbb { sql:variable("@b") } after (zzz/bbb)[1]')

SELECT @xml [after], DATALENGTH(@xml) dl
4
wBob