2011-07-21 2 views
3

標準化された構造に変換する必要があるSQL Server 2005に格納されている(型なしの)XMLがあります。文書の構造は、現在、そのようになっていますSQL Server 2005のXML APIを使用してXMLフラグメントを正規化する

<wrapper> 
<parent /> 
<node /> 
<node /> 
<node /> 

<parent /> 
<node /> 
<node /> 
<node /> 
<wrapper> 

私はそれがこのように見えるように変換したい:

<wrapper> 
<parent> 
    <node /> 
    <node /> 
    <node /> 
</parent> 
<parent> 
    <node /> 
    <node /> 
    <node /> 
</parent> 
<wrapper> 

私はにXMLを選択することができます私が必要な場合、リレーショナル構造は、問題を置く属性が親と子ノードを一緒にリンクしていないので、注文が問題になるときにusin gセットベースの操作。 .nodes()/。value()/その他のSQL Server XML APIを使用してこのデータを変換するにはどうすればよいですか。変換はバッチSQLスクリプトの一部として実行する必要がありますので、別のツール/言語に展開することは私にとっては妥当な選択肢ではありません。実際

+1

SQL Serverで妥当な努力をしてこのようなことを行うことができますか。そのXQueryエンジンは、XMLにクエリを出してそこからデータを抽出するのに適しています。操作面で重く持ち上げるほどです。私はあなたがSQL ServerからそのXMLを取得する方が良いと思います。 C#/。NETとそこに修正を行い、それを保存します。 –

答えて

1

- コードの作品以下(ここでは、グループ化することも、非常に最適ではないですが、とにかく):

declare @xml xml = ' 
    <wrapper> 
    <parent id="1" /> 
    <node id="1" /> 
    <node id="2" /> 
    <node id="3" /> 

    <parent id="2" /> 
    <node id="4" /> 
    <node id="5" /> 
    <node id="6" /> 
    </wrapper> 
' 

;with px as 
(
    select row_number() over (order by (select 1)) as RowNumber 
     ,t.v.value('@id', 'int') as Id 
     ,t.v.value('local-name(.)', 'nvarchar(max)') as TagName 
    from @xml.nodes('//wrapper/*') as t(v) 
) 
select p.Id as [@id], 
    (
     select n.Id as id 
     from px n 
     where n.TagName = 'node' 
      and n.RowNumber > p.RowNumber 
      and not exists 
      (
       select null 
       from px np 
       where np.TagName = 'parent' 
        and np.RowNumber > p.RowNumber 
        and np.RowNumber < n.RowNumber 
      ) 
     order by n.RowNumber 
     for xml raw('node'), type 
    ) 
from px p 
where p.TagName = 'parent' 
order by p.RowNumber 
for xml path('parent'), root('wrapper')

しかし、私はそれを使用することをお勧めしません。ここをクリックしてください:http://msdn.microsoft.com/en-us/library/ms172038%28v=sql.90%29.aspx

SQLXML 4.0では、文書の順序は必ずしも確定していません
私はラッパーの中でタグの順序に頼ることができないと思います(上記のコードは実用的ではありません)。

+0

入力いただきありがとうございます。私は同じ結論に達しました。これは非確定的です。私は他の何かを把握します。 –

+0

@jonathan - 数値テーブルを使って 'position()'を使って、確定的な方法で行を列挙することができます。この答えを見てください。 http://stackoverflow.com/questions/6472533/xquery-and-node-ids/6473228#6473228 –

+1

素晴らしい解決策!私はvalue関数でposition()を使用しようとしましたが、助けになりませんでした(位置は述語の内部でしか使用できません)。 – oryol

関連する問題