web-dev-qa-db-fra.com

Comment ajouter le codage xml <? Xml version = "1.0" encoding = "UTF-8"?> À la sortie xml dans SQL Server

Probablement une copie dupliquée de . SQL Server 2008 - Ajouter une déclaration XML à une sortie XML

S'il vous plaît laissez-moi savoir si cela est possible. Je lis dans certains blogs 

http://forums.asp.net/t/1455808.aspx/1

http://www.devnewsgroups.net/group/Microsoft.public.sqlserver.xml/topic60022.aspx

Mais je ne comprenais pas pourquoi je ne pouvais pas faire ça.

19
001priyank

Vous devez l'ajouter manuellement. SQL Server stocke toujours le fichier XML en interne sous le nom ucs-2; il est donc impossible pour SQL de générer un en-tête de codage utf-8.

Voir "Limitations du type de données xml" sur MSDN

La déclaration XML PI, par exemple, <?xml version='1.0'?>, n'est pas conservée lors du stockage de données XML dans une instance de type de données xml. C'est par conception. La déclaration XML (<?xml ... ?>) et ses attributs (version/encoding/stand-alone) sont perdus après la conversion des données en type xml. La déclaration XML est traitée comme une directive adressée à l'analyseur XML. Les données XML sont stockées en interne sous le nom ucs-2.

35
gbn

Quand j'ai lu cet article, j'ai pensé que c'était le "bout de la ligne" ... pas de solution ... j'ai presque abandonné l'approche ... mais en fait, il existe un moyen de contourner cette limitation en convertissant le code XML varchar (max), puis en ajoutant la déclaration au début de la chaîne. Le post suivant montre comment:

Utilisation de SQL Server "FOR XML": Convertir le type de données de résultat en Text/varchar/string

Un exemple simple ressemblerait à ceci:

SELECT 'MY DATA' As MyColumn INTO #MyTable 
SELECT '<?xml version="1.0" encoding="UTF-8"?>' + 
CAST((SELECT MyColumn FROM #MyTable FOR XML PATH('')) AS VARCHAR(MAX)) AS XmlData
DROP TABLE #MyTable 

Le résultat:

<?xml version="1.0" encoding="UTF-8"?>
<MyColumn>MY DATA</MyColumn>
5
MichaelBarce

La réponse acceptée de "l'ajouter manuellement", alors que techniquement} est correcte, est incomplète et donc trompeuse. Ajouter simplement la déclaration XML avec le "codage" de votre choix ne modifie pas le codage réel de la chaîne. C'est parfois ok. Si vous spécifiez "UTF-8" et convertissez les données XML en VARCHAR, tant que tous des caractères sont des caractères standard ASCII (valeurs 1 - 127), il s'agit bien de UTF. -8 (au moins il n'y a pas de différence notable). MAIS, s'il y a aucun caractères avec des valeurs supérieures ou égales à 128, vous avez alors pas un document XML codé en UTF-8. Et si vous convertissez les données XML en NVARCHAR, vous disposez alors d'un document codé UTF-16, indépendamment de ce que vous spécifiez manuellement dans la déclaration XML. Vous ne devez spécifier qu'un codage SI c'est le codage réel utilisé.

Et jusqu'à SQL Server 2019 (actuellement en version bêta à CTP 2.1), il n'y avait aucun moyen d'obtenir le codage au format UTF-8 dans SQL Server, du moins sans utiliser SQLCLR. Mais dans SQL Server 2019, vous pouvez maintenant convertir le XML en UTF-8 réel:

DECLARE @XML XML;
SET @XML = N'<test attr="&#x1F60E;"/>';
SELECT @XML,
       CONVERT(VARBINARY(100), CONVERT(NVARCHAR(MAX), @XML)), -- UTF-16 / UCS-2
       CONVERT(VARBINARY(100),
               CONVERT(VARCHAR(MAX),
                       CONVERT(NVARCHAR(MAX), @XML) COLLATE Latin1_General_100_CI_AS_SC_UTF8)
              ); -- UTF-8

Cela retourne:

Column 1: <test attr="????" />
Column 2: 0x3C007400650073007400200061007400740072003D0022003DD80EDE22002F003E00
Column 3: 0x3C7465737420617474723D223F3F222F3E

Etant donné que de nombreuses personnes ne seront pas encore sur SQL Server 2019 avant, ceci est possible via SQLCLR. Vous pouvez utiliser les classes .NET Xml (par exemple, XmlWriter) pour l’exporter avec diverses options. En fait, j'ai créé une bibliothèque de fonctions SQLCLR, SQL # , qui inclut une telle fonction: XML_SaveToFile. La fonction XML_SaveToFile permet de spécifier tout codage valide. Elle le définira dans la déclaration XML et garantira que le fichier est enregistré avec ce codage. Il a également des options pour l'indentation, les nouvelles lignes, etc. Just FYI: alors que de nombreuses fonctions sont disponibles dans la version gratuite, XML_SaveToFile n'est disponible que dans la version complète (payante).

2
Solomon Rutzky

J'ai travaillé sur cette question au cours des derniers jours et, même s'il existe peut-être de meilleures solutions, je suis plutôt satisfait de ce script bash:

iconv -f UCS-2 -t UTF-8 products.xml > products_utf8.xml
echo "<?xml version='1.0'?>\n<products>\n$(cat products_utf8.xml)\n</products>" > products_utf8_final.xml

Fondamentalement, ce script obtiendra un fichier généré à partir du logiciel horrible bcp, qui génère des données XML incomplètes et non valides, le convertira du format UCS-2 au format UTF-8 (première ligne), et ajoutera au début et à la fin du fichier. ce dont il a besoin (deuxième ligne du script) pour être valide et complet.

Ça marche pour moi. Le script que j'ai utilisé pour générer le fichier XML avec BCP est le suivant:

bcp.exe "select * from dat1.dbo.Products FOR XML AUTO,ELEMENTS” queryout "C:\products.xml" -T -w -r -S .\SQLEXPRESS