我们有一个源XML
文件,其中包含address
个节点,并且每个节点都应该在下面有一个zip_code
节点才能进行验证。我们收到了一个未通过架构验证的文件,因为至少有一个节点缺少它的zip_code(文件中有几千个地址)。
我们需要找到没有邮政编码的元素,这样我们就可以修复文件并将审核报告发送给源。
--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
的{{1}}值的演员表,但它确实有效,但我不确定它应该如此。我尝试了.exist
函数的一些变体,但是我无法得到正确的结果。
答案 0 :(得分:4)
如果您只是想确保选择具有address
元素的zip_code
元素,请调整XPATH以在谓词过滤器中包含该条件:
/addresses/address[zip_code]
如果您还想确保zip_code
元素也有值,请使用zip_node
的谓词过滤器来选择具有text()
个节点的谓词过滤器:
/addresses/address[zip_code[text()]]
修改强>
实际上,我正在寻找 相反。我需要识别节点 没有拉链,所以我们可以 手动更正源数据。
因此,如果您要识别不具有address
的所有zip_code
元素,您可以在XPATH中指定它,如下所示:
/addresses/address[not(zip_code)]
答案 1 :(得分: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节点内是否存在子节点。