代码之家  ›  专栏  ›  技术社区  ›  Moslem Ben Dhaou Ahmed ilyas

从具有多个命名空间的XML中选择值

  •  1
  • Moslem Ben Dhaou Ahmed ilyas  · 技术社区  · 7 年前

    我需要从XML列中读取属性的值。数据是一个声明了多个名称空间的XML:

    <sd:objectData xmlns:sd="http://sd-uri">
        <sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
            <do:properties xmlns:do="http://do-uri">
                <do:property name="DECISION">
                    <do:propertyValues clearExistingValues="true">
                        <do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
                    </do:propertyValues>
                </do:property>
            </do:properties>
        </sd:object>
    </sd:objectData>
    

    我想读取 valueInteger ,即在本例中 1000142 . 我试过了 WITH XMLNAMESPACES() 但我无法将其结合起来定义这两个别名。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Thom A    7 年前

    这对你有用吗?

    DECLARE @XML xml = '
    <sd:objectData xmlns:sd="http://sd-uri">
        <sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
            <do:properties xmlns:do="http://do-uri">
                <do:property name="DECISION">
                    <do:propertyValues clearExistingValues="true">
                        <do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
                    </do:propertyValues>
                </do:property>
            </do:properties>
        </sd:object>
    </sd:objectData>';
    
    WITH XMLNAMESPACES ('http://sd-uri' AS sd,
                        'http://do-uri' AS do)
    SELECT @XML.value('(/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/@valueInteger)[1]','int') AS valueInteger;
    
        2
  •  2
  •   Community CDub    4 年前

    除了Larnu的答案(这是最佳且正确的答案)之外,如果您只想获得一个值,还可以选择一些快捷方式:

    此查询通过四种不同的方法获取所需的值

    SELECT @XML.value(N'(//*/@valueInteger)[1]',N'int') AS Super_easy_with_double_wildcard
          ,@XML.value(N'(//*:propertyValue/@valueInteger)[1]',N'int') AS Easy_with_namespace_wildcard
          ,@XML.value(N'declare namespace do="http://do-uri";
                        (//do:propertyValue/@valueInteger)[1]',N'int') AS with_local_declaration
          ,@XML.value(N'declare namespace do="http://do-uri";
                        declare namespace sd="http://sd-uri";
                        (/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/@valueInteger)[1]',N'int') AS with_full_local_declaration;
    

    一般建议如下: 尽可能具体以避免麻烦 . 如果你不费事,只需要一个可读的、快速的捕获,你可以选择其中一个。

    更新添加谓词

    使用谓词可以放置筛选器:

    SELECT @XML.value(N'(//*:property[@name="DECISION"]//*:propertyValue/@valueInteger)[1]',N'int') AS Example_with_predicate