web-dev-qa-db-ja.com

SQL 2005でFOR XML PATHを使用しながらアンパサンド(&)を保持する方法

SQL Serverが&、<、>などの文字を認証できないようにするためのトリックはありますか? XMLファイルにURLを出力しようとしていますが、SQLは '&'を '&amp;'に置き換えようとしています

次のクエリを見てください。

SELECT 'http://foosite.com/' + RTRIM(li.imageStore)
        + '/ImageStore.dll?id=' + RTRIM(li.imageID)
        + '&raw=1&rev=' + RTRIM(li.imageVersion) AS imageUrl
FROM ListingImages li
FOR XML PATH ('image'), ROOT ('images'), TYPE

私が得る出力は次のようなものです(&sはentitizedです):

<images>
  <image>
    <imageUrl>http://foosite.com/pics4/ImageStore.dll?id=7E92BA08829F6847&amp;raw=1&amp;rev=0</imageUrl>
  </image>
</images>

私が欲しいのはこれです(&sはentitizedされていません):

<images>
  <image>
    <imageUrl>http://foosite.com/pics4/ImageStore.dll?id=7E92BA08829F6847&raw=1&rev=0</imageUrl>
  </image>
</images>

SQLサーバーが '&'を '&amp;'に認証できないようにするにはどうすればよいですか?

30
Duffy

SQL Serverが生成するものは正しいです。期待するのは、整形式のXMLではありません。その理由は、&文字が&amp;などのエンティティ参照の開始を示すためです。詳細は XML仕様 を参照してください。

XMLパーサーがこの文字列をXMLから解析すると、&amp;エンティティ参照が理解され、テキストが必要な形式で返されます。したがって、バグのあるXMLパーサーを使用するか、手動で解析しようとしない限り、XMLファイルの内部形式は問題を引き起こしません(この場合、現在のパーサーコードは現在、XMLに関して事実上バグがあります)仕様)。

10
ykaganovich

人が整形式のXMLを望まない場合があります-私(およびおそらく元の投稿者)が遭遇したのは、For XML Path手法を使用して、再帰クエリを介して「子」アイテムの単一フィールドリストを返すことでした。この手法の詳細については、次を参照してください(特に「ブラックボックスXMLメソッド」セクション): Transact-SQLでの行の値の連結

私の状況では、「H&E」(病理​​学の汚れ)が「整形式のXML」に変換されるのを見るのは本当にがっかりした。幸い、解決策を見つけました...次のページは、この問題を比較的簡単に解決するのに役立ちました。再帰クエリを再構築したり、プレゼンテーションレベルで追加の解析を追加したりする必要はありませんでした-rowsデータフィールドには予約済みのXML文字が含まれます): FOR XML PATHを使用した特殊文字の処理


編集:参照されたブログ投稿からの以下のコード。

select
  stuff(
     (select ', <' + name + '>'
     from sys.databases
     where database_id > 4
     order by name
     for xml path(''), root('MyString'), type
     ).value('/MyString[1]','varchar(max)')
   , 1, 2, '') as namelist;
56
Janmonn

これを試して....

select 
  stuff( 
     (select ', <' + name + '>' 
     from sys.databases 
     where database_id > 4 
     order by name 
     for xml path(''), root('MyString'), type 
     ).value('/MyString[1]','varchar(max)') 
   , 1, 2, '') as namelist;