web-dev-qa-db-ja.com

xmlエンコーディング<?xml version = "1.0" encoding = "UTF-8"?>をSQL Serverのxml出力に追加する方法

おそらく未回答の複製。 SQL Server 2008-XML宣言へのXML出力の追加

これが可能かどうか教えてください。いくつかのブログを読んだ

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

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

しかし、なぜこれができないのか理解できませんでした。

19
001priyank

手動で追加する必要があります。 SQL Serverは常にxmlをucs-2として内部に保存するため、SQLがutf-8エンコーディングヘッダーを生成することはできません

MSDNの "xmlデータ型の制限" を参照してください。

XML宣言PI。たとえば、<?xml version='1.0'?>は、XMLデータをxmlデータ型のインスタンスに保存するときに保持されません。これは仕様です。 XML宣言(<?xml ... ?>)およびその属性(バージョン/エンコード/スタンドアロン)は、データがxml型に変換された後に失われます。 XML宣言は、XMLパーサーへのディレクティブとして扱われます。 XMLデータは、ucs-2として内部的に保存されます。

36
gbn

この投稿を読んだとき、私はそれが「行末」だと思った...解決策はない...私はアプローチをほとんどあきらめた...しかし、実際にはXMLを変換することでこの制限を回避する方法があるvarchar(max)に追加し、宣言を文字列の先頭に追加します。次の投稿はその方法を示しています。

SQL Server "FOR XML"を使用:結果データ型をText/varchar/string何に変換しますか?

簡単な例は次のようになります。

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 

出力:

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

「手動で追加する」という受け入れられた答えは、技術的に正解ですが、不完全であり、誤解を招く可能性があります。必要な「エンコード」でXML宣言を追加するだけでは、文字列の実際のエンコードは変更されません。これは時々大丈夫です。 「UTF-8」を指定し、XMLデータをVARCHARに変換する場合、文字のallが標準のASCII文字(値1-127)である限り、そして確かに、それはUTF-8です(少なくとも顕著な違いはありません)。ただし、値が128以上のany文字がある場合、notUTF-8でエンコードされたXMLドキュメントはありません。 XMLデータをNVARCHARに変換すると、XML宣言で手動で指定した内容に関係なく、UTF-16でエンコードされたドキュメントが作成されます。実際に使用されているエンコーディングの場合にのみ、エンコーディングを指定する必要があります。

SQL Server 2019(現在はCTP 2.1のベータ版)まで、少なくともSQLCLRを使用しない限り、SQL Server内でエンコードをUTF-8にする方法はありませんでした。しかし、SQL Server 2019では、XMLを実際のUTF-8に変換できるようになりました。

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

それは返します:

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

多くの人はまだしばらくの間SQL Server 2019を使用しないため、これはSQLCLRを介して可能です。 .NET Xmlクラス(XmlWriterなど)を使用して、さまざまなオプションでこれをエクスポートできます。実際、関数のSQLCLRライブラリ SQL# を作成しました。これには、そのような関数が含まれています:XML_SaveToFileXML_SaveToFile関数を使用すると、有効なエンコーディングを指定でき、XML宣言でそれを設定し、ファイルがそのエンコーディングで保存されるようにします。インデント、改行などのオプションもあります。参考までに:無料版では多くの機能が利用できますが、XML_SaveToFileはFullでのみ利用可能です(有料)バージョン。

2
Solomon Rutzky

私は最後の数日間この問題に取り組んできましたが、より良い解決策はあるかもしれませんが、この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

基本的に、このスクリプトは、不完全で無効なXMLデータを生成する恐ろしいbcpソフトウェアから生成されたファイルを取得し、UCS-2形式からUTF-8(最初の行)に変換し、ファイルの最初と最後に追加します有効で完全であるために必要なもの(スクリプトの2行目)。

わたしにはできる。 BCPでXMLファイルを生成するために使用したスクリプトは次のとおりです。

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