TSQL 中搜索 xml 查找不存在节点的更好方法
我们有一个源 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
,并且它有效,但我不太确定它应该这样做。我尝试了 .exist
函数的一些变体,但无法获得正确的结果。
We have a source XML
file that has an address
node, and each node is supposed to have a zip_code
node beneath in order to validate. We received a file that failed the schema validation because at least one node was missing it's zip_code (there were several thousand addresses in the file).
We need to find the elements that do not have a zip code, so we can repair the file and send an audit report to the source.
--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
Really, it's the where
clause that bugs me. I feel like I'm depending on a cast for a null
value to 0
, and it works, but I'm not really sure that it should. I tried a few variations with the .exist
function, but I couldn't get the correct result.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您只是想确保选择具有
zip_code
元素的address
元素,则调整您的 XPATH 以在谓词过滤器中包含该条件:如果您还想确保
zip_code
元素也有一个值,对zip_node
使用谓词过滤器来选择那些具有text()
节点的节点:编辑:
因此,如果您想识别所有没有
zip_code
的address
元素,您可以在 XPATH 中指定它,如下所示:If you just want to ensure that you are selecting
address
elements that have azip_code
element, then adjust your XPATH to include that criteria in a predicate filter:If you also want to ensure that the
zip_code
element also has a value, use a predicate filter for thezip_node
to select those that havetext()
nodes:EDIT:
So, if you want to identify all of the
address
elements that do not have azip_code
, you can specify it in the XPATH like this:如果您只想找到那些缺少
元素的节点,您可以使用如下内容:它使用内置的
.exist()
方法在 XQuery 中检查 XML 节点内是否存在子节点。If you just want to locate those nodes that are missing their
<zip_code>
element, you could use something like this:It uses the built-in
.exist()
method in XQuery to check the existence of a subnode inside an XML node.