在TSQL中使用命名空间解析XML - 子详细信息

时间:2018-05-31 10:27:47

标签: xml tsql

我有xml如下所示,我已经设法一次获得了physicalAddress的一个变量,但我想获取子注释中的所有现有记录(如果存在),否则我有重复的问题。

期望的结果是将所有子记录放在一列中以反映每个记录的详细信息,因此如果有5个地址,我将在每行中有5个地址部分不同的记录

感谢您的帮助。

谢谢

使用的XML:

 `<PostData xmlns="mypath">
 <data>
     <Studentebo:CurrentEBO xmlns:Studentebo="MMMMMMM">
     <Studentebo:Person>       
        <ns6:PersonName xmlns:ns6="ZZZZZZZZZZZZZZ" xmlns="ZZZZZZZZZZZZZZ">
           <ns6:FirstName>Example3</ns6:FirstName>
           <ns6:MiddleName>Example3</ns6:MiddleName>
           <ns6:LastName>Example4</ns6:LastName>
           <ns6:PreferredName>testTest4</ns6:PreferredName>
           <ns6:Title>MRS.</ns6:Title>
        </ns6:PersonName>        
        <ns6:PhysicalAddresses xmlns:ns6="ZZZZZZZZZZZZZZ" 
            xmlns="ZZZZZZZZZZZZZZ">
           <ns6:PhysicalAddress>
              <ns15:Identification xmlns:ns15="OOOOO" xmlns="OOOOO">
                 <ns15:AddressNumber>125a6407-1b91-4d2c-a783- 
                 280127f38249</ns15:AddressNumber>
              </ns15:Identification>
              <ns15:AddressUsages xmlns:ns15="XXXXXXX" xmlns="XXXXXXX">
                 <ns15:AddressUsage>
                    <ns9:UsageCode xmlns:ns9="QQQQQ" 
                          xmlns="QQQQQ">HOME</ns9:UsageCode>
                 </ns15:AddressUsage>
              </ns15:AddressUsages>
              <ns15:EffectiveDates xmlns:ns15="XXXXXXX" xmlns="XXXXXXX">
                 <ns12:StartDateTime xmlns:ns12="LLLLLL" 
                         xmlns="LLLLLL">2018-01- 
                      07T00:00:00+00:00</ns12:StartDateTime>
                 <ns12:EndDateTime xmlns:ns12="LLLLLL" xmlns="LLLLLL">2064- 
                01-03T00:00:00+00:00</ns12:EndDateTime>
              </ns15:EffectiveDates>
              <Address1 xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">Testing Address 
                        line2</Address1>
              <Address2 xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">test4 
                    line2</Address2>
              <Address3 xmlns:ns12="XXXXXXX" x 
                       mlns="XXXXXXX">line33</Address3>
              <City xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">Testing</City>
              <PostalCode xmlns:ns12="XXXXXXX" 
                xmlns="XXXXXXX">Testing</PostalCode>
              <Country xmlns:ns12="XXXXXXX" 
                         xmlns="XXXXXXX">Testing</Country>
           </ns6:PhysicalAddress>
           <ns6:PhysicalAddress>
              <ns15:Identification xmlns:ns15="OOOOO" xmlns="OOOOO">
                 <ns15:AddressNumber>125a6407-1b91-4d2c-a783- 
                 280127f38249</ns15:AddressNumber>
              </ns15:Identification>
              <ns15:AddressUsages xmlns:ns15="XXXXXXX" xmlns="XXXXXXX">
                 <ns15:AddressUsage>
                    <ns9:UsageCode xmlns:ns9="QQQQQ" 
                 xmlns="QQQQQ">HOME</ns9:UsageCode>
                 </ns15:AddressUsage>
              </ns15:AddressUsages>
              <ns15:EffectiveDates xmlns:ns15="XXXXXXX" xmlns="XXXXXXX">
                 <ns12:StartDateTime xmlns:ns12="LLLLLL" 
                     xmlns="LLLLLL">2018-01- 
                         07T00:00:00+00:00</ns12:StartDateTime>
                 <ns12:EndDateTime xmlns:ns12="LLLLLL" xmlns="LLLLLL">2064- 
       01-03T00:00:00+00:00</ns12:EndDateTime>
              </ns15:EffectiveDates>
              <Address1 xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">Testing Address 
            line2</Address1>
              <Address2 xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">test4 
             line2</Address2>
              <Address3 xmlns:ns12="XXXXXXX" 
                  xmlns="XXXXXXX">line33</Address3>
              <City xmlns:ns12="XXXXXXX" xmlns="XXXXXXX">Testing</City>
              <PostalCode xmlns:ns12="XXXXXXX" 
                  xmlns="XXXXXXX">Testing</PostalCode>
              <Country xmlns:ns12="XXXXXXX" 
                     xmlns="XXXXXXX">Testing</Country>
           </ns6:PhysicalAddress>
        </ns6:PhysicalAddresses>            
           </Studentebo:Person>
      <Studentebo:CurrentEBO>

使用SELECT:

SELECT id, t.r.value('
                 declare namespace C1="mypath";
                 declare namespace CAM1="MMMMMMM";
                 declare namespace C2="ZZZZZZZZZZZZZZ";
                 declare namespace CAM2="OOOOO";
                       (.)', 'varchar(50)') as address1
FROM
[XXX_SH_SOAService_formattedXML] OUTER APPLY
[XML].nodes('
                 declare namespace C1="mypath";
                 declare namespace CAM1="MMMMMMM";
                 declare namespace C2="ZZZZZZZZZZZZZZ";
                 declare namespace CAM2="OOOOO";

 /C1:PostData/C1:data/CAM1:CurrentEBO/ 
 CAM1:Person/C2:PhysicalAddresses/C2:PhysicalAddress/CAM2:Address1') t(r)

1 个答案:

答案 0 :(得分:0)

如果这个XML的构建在你的控制之下你应该尝试改变这些命名空间的混乱......特别难以看出一个元素在新定义的默认命名空间中反复使用哪个ns

在大多数情况下,最好是尽可能具体。但是在这里我建议通过在任何地方使用通配符来忽略名称空间:

SELECT t.ID 
      ,pers.value(N'(*:PersonName/*:FirstName/text())[1]',N'nvarchar(200)') AS Person_FirstName
      --more of Person
      ,addr.value(N'(*:Identification/*:AddressNumber/text())[1]',N'uniqueidentifier') AS Address_Number
      --AddressUsage would need one more `.nodes()`, as it is 1:n within each address
      ,addr.value(N'(*:EffectiveDates/*:StartDateTime/text())[1]',N'datetime2') AS Address_StartDateTime
      ,addr.value(N'(*:Address1/text())[1]',N'nvarchar(max)') AS Address_Address1
      ,addr.value(N'(*:Address2/text())[1]',N'nvarchar(max)') AS Address_Address2
      ,addr.value(N'(*:Address3/text())[1]',N'nvarchar(max)') AS Address_Address3
      ,addr.value(N'(*:City/text())[1]',N'nvarchar(max)') AS Address_City
      --more of the same
FROM @tbl AS t
OUTER APPLY t.YourXml.nodes(N'/*:PostData/*:data/*:CurrentEBO/*:Person') A(pers)
OUTER APPLY pers.nodes(N'*:PhysicalAddresses/*:PhysicalAddress') B(addr);

我不赞成这个:

  

我会有5条记录,每行的地址部分不同

但是上面应该指明你的方式......