2011-01-03 18 views
3

addressノードを持つソースXMLファイルがあり、各ノードの検証にはzip_codeノードがあるはずです。少なくとも1つのノードにzip_codeが存在しないため(ファイルに数千のアドレスがあるため)、スキーマの検証に失敗したファイルを受信しました。存在しないノードのxmlを検索するTSQLの方が良い

私たちはファイルを修復し、ソースに監査レポートを送信するために、郵便番号を持たない要素を見つける必要があります。

--declare @x xml = bulkcolumn from openrowset(bulk 'x:\file.xml',single_blob) as s 
declare @x xml = N'<addresses> 
    <address><external_address_id>1</external_address_id><zip_code>53207</zip_code></address> 
    <address><external_address_id>2</external_address_id></address> 
</addresses>' 

declare @t xml = (
select @x.query('for $a in .//address 
    return 
     if ($a/zip_code) 
      then <external_address_id /> 
     else $a/external_address_id') 
) 
select x.AddressID.value('.', 'int') AddressID 
from @t.nodes('./external_address_id') x(AddressID) 
where x.AddressID.value('.', 'int') > 0 
GO 

実際には、それはバグと私はwhere句です。私はnullの値を0にキャストしているような気がしていますが、それはうまくいきますが、それはすべきことではありません。 .exist機能でいくつかのバリエーションを試しましたが、正しい結果が得られませんでした。

答えて

2

あなたがちょうど彼らの<zip_code>要素が欠落しているそれらのノードの位置を特定したい場合、あなたはこのようなものを使用することができますが:

SELECT 
    ADRS.ADR.value('(external_address_id)[1]', 'int') as 'ExtAdrID' 
FROM 
    @x.nodes('/addresses/address') as ADRS(ADR) 
WHERE 
    ADRS.ADR.exist('zip_code') = 0 

それはビルトインのXQueryで.exist()方法サブノードの存在を確認するために使用していますXMLノード内

/addresses/address[zip_code] 

あなたはまた、そのようにしたい場合は:あなたはちょうどあなたがzip_code要素を持っているaddress要素を選択していることを確認したい場合は

4

、述語フィルタで基準があること含めるようにXPATHを調整

/addresses/address[zip_code[text()]] 

zip_code要素も text()ノードを有するものを選択する zip_nodeため述語のフィルタを使用し、値を持ちます

EDIT:実際

、私は 反対を探しています。ノード にはzipがないので、 ソースデータを手動で修正する必要があります。

あなたはzip_codeを持っていないことaddressのすべての要素を特定したいのであれば、あなたはこのようなXPATHでそれを指定することができます。

/addresses/address[not(zip_code)] 
+0

1良い答え。 –

+0

実際、私はその反対を探しています。 zipを持たないノードを特定する必要があるため、ソースデータを手動で修正することができます。 –

+0

申し訳ありませんが、私は誤解しました。私は 'zip_code'を持たない' address'要素だけをどのように扱うことができるかの例を更新しました。 –

関連する問題