sql - XML 到 SQL - 选择多个同名节点

标签 sql sql-server xml

我有可以从 XML 文件中选择一些值的工作代码。问题是我有多个同名节点。

这是 XML 的片段:

<wd:Report_Data xmlns:wd="urn:com.workday.report/Countries_and_Their_Address_Components_Summary">
  <wd:Report_Entry>
    <wd:Country wd:Descriptor="Afghanistan">
      <wd:ID wd:type="WID">db69b722446c11de98360015c5e6daf6</wd:ID>
      <wd:ID wd:type="ISO_3166-1_Alpha-2_Code">AF</wd:ID>
      <wd:ID wd:type="ISO_3166-1_Alpha-3_Code">AFG</wd:ID>
      <wd:ID wd:type="ISO_3166-1_Numeric-3_Code">4</wd:ID>
    </wd:Country>
    <wd:Address_Format_Type wd:Descriptor="Basic">
      <wd:ID wd:type="WID">4516bf435611423ea4ee72fa842572a0</wd:ID>
    </wd:Address_Format_Type>
    <wd:Local>1</wd:Local>
    <wd:Address_Components>
      <wd:Address_Component wd:Descriptor="Address Line 1 - Local">
        <wd:ID wd:type="WID">12d859b8df024175a111da2e088250fb</wd:ID>
        <wd:ID wd:type="Address_Component_Type_ID">ADDRESS_LINE_1_LOCAL</wd:ID>
      </wd:Address_Component>
      <wd:Order>a</wd:Order>
      <wd:Required>0</wd:Required>
    </wd:Address_Components>
    <wd:Address_Components>
      <wd:Address_Component wd:Descriptor="Address Line 2 - Local">
        <wd:ID wd:type="WID">85a6ab9412c44dd9a71a7e4760bf17fb</wd:ID>
        <wd:ID wd:type="Address_Component_Type_ID">ADDRESS_LINE_2_LOCAL</wd:ID>
      </wd:Address_Component>
      <wd:Order>b</wd:Order>
      <wd:Required>0</wd:Required>
    </wd:Address_Components>

我的 SQL 如下:

declare @inputxml table (x xml)

insert @inputxml
select x
from OPENROWSET(BULK 'C:\ParallelTool\addcomp.xml', SINGLE_BLOB) As T(x)

;WITH XMLNAMESPACES(DEFAULT 'urn:com.workday.report/Countries_and_Their_Address_Components_Summary')
    select 
        xmldata.[ISO], xmldata.[Component 1], xmldata.[Component 2], xmldata.[Required]
    into dbo.WD
    from @inputxml
    cross apply (
        select 
            [ISO] = xmldata.value('(Country/ID)[3]', 'VARCHAR(MAX)'),
            [Component 1] = xmldata.value('(Address_Components/Address_Component/ID)[2]', 'VARCHAR(MAX)'),
            [Component 2] = xmldata.value('(Address_Components/Address_Component/ID)[2]', 'VARCHAR(MAX)'),
            [Required] = xmldata.value('(Address_Components/Required)[1]', 'INT')
        from x.nodes('/Report_Data/Report_Entry') Z1(xmldata)
    ) xmldata

我无法获得我需要的东西的是[组件2]。我基本上想选择文件中的所有“Address_Component_Type_ID”,但它们的名称都相同,并且位于名称相同的其他节点下。如何在 SQL 中指定获取所有组件类型?感谢您的浏览!

最佳答案

取决于你想要做什么...如果你知道你想要获取正好有 2 个“Address_Components”,你可以像这样修改你的查询:

;WITH XMLNAMESPACES(DEFAULT 'urn:com.workday.report/Countries_and_Their_Address_Components_Summary')
    select 
        xmldata.[ISO], xmldata.[Component 1], xmldata.[Component 2], xmldata.[Required]
    from @inputxml
    cross apply (
        select 
            [ISO] = xmldata.value('(Country/ID)[3]', 'VARCHAR(MAX)'),
            [Component 1] = xmldata.value('(Address_Components/Address_Component/ID)[2]', 'VARCHAR(MAX)'),
            [Component 2] = xmldata.value('(Address_Components[2]/Address_Component/ID)[2]', 'VARCHAR(MAX)'),
            [Required] = xmldata.value('(Address_Components/Required)[1]', 'INT')
        from x.nodes('/Report_Data/Report_Entry') Z1(xmldata)
    ) xmldata

结果如下所示:

ISO   Component 1               Component 2               Required
----- ------------------------- ------------------------- -----------
AFG   ADDRESS_LINE_1_LOCAL      ADDRESS_LINE_2_LOCAL      0

但是,如果可以有任意数量的“Address_Components”,并且您希望将它们抓取到单独的记录中,则可以像这样重写查询:

;WITH XMLNAMESPACES(DEFAULT 'urn:com.workday.report/Countries_and_Their_Address_Components_Summary')
    select 
        [ISO] = Report_Entry.x.value('(Country/ID)[3]', 'VARCHAR(MAX)')
        , [Component] = Address_Components.x.value('(Address_Component/ID)[2]', 'VARCHAR(MAX)')
        , [Required] = Address_Components.x.value('(Required)[1]', 'INT')
    from @inputxml
    cross apply x.nodes('/Report_Data/Report_Entry') Report_Entry(x)
    cross apply Report_Entry.x.nodes('./Address_Components') Address_Components (x)

结果如下所示:

ISO   Component                 Required
----- ------------------------- -----------
AFG   ADDRESS_LINE_1_LOCAL      0
AFG   ADDRESS_LINE_2_LOCAL      0

关于sql - XML 到 SQL - 选择多个同名节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22178863/

相关文章:

mysql - SQL检查表中的值是否在另一个表中的2列范围内

sql - 如何使用 group by 计算总和?

sql-server - LogParser:SQL 表列 "X"数据类型与 SELECT 子句项 "cs-username"(类型 STRING)不兼容

xml - 将 xml 标签名称提取到 xml 属性值中

c# - 选择另一个旁边的特定节点 - C# - SelectSingleNode

javascript - 在 XML 表属性中设置条件 (SAP UI5)

sql - Postgres 通过另一列在列组中获取至少具有 1 个特定值的行

sql - 在 postgresql 中将 jsonb 值转换为 varchar

php - 格式化查询输出 : using sql or php functions?

sql-server - 如何从节点获取值(value)? SQL Server XML dml