无法解析 XML

Not able to parse XML

我需要帮助将 XML 变量解析为 table 格式,如下所示。我是在 google 中查找的解析新手,能够解析 AccountIdEmailProductNameProductType,但无法解析具有 in 属性的节点像 CustNameCreatedDatebillingCode

   DECLARE @xmlvalue XML = 
'<Request>
  <AccountId>16000</AccountId>
  <Email>test@gmail.com</Email>
  <Attributes>
  <Attribute><Name xmlns="http://testtarget.com/wsdl/myAPI">CustName</Name><Value xmlns="http://testtarget.com/wsdl/myAPI">TestName</Value></Attribute>
  <Attribute><Name xmlns="http://testtarget.com/wsdl/myAPI">CreatedDate</Name><Value xmlns="http://testtarget.com/wsdl/myAPI">3/26/2022</Value></Attribute>
  <Attribute><Name xmlns="http://testtarget.com/wsdl/myAPI">BillingCode</Name><Value xmlns="http://testtarget.com/wsdl/myAPI">testbiling</Value></Attribute>
  </Attributes>
  <ProductName>TestProduct</ProductName>
  <ProductType>Recurring</ProductType>
</Request>'

预期输出:

AccountId  Email           CustName  CreatedDate  BillingCode  ProductName ProductType
1600       test@gmail.com  TestName   03/26/2022  testbiling  TestProduct  Recurring

下面的代码给了我想要的东西。有没有简单的方法?

SELECT req.req_col.value('AccountId[1]','INT')       AS AccountId, 
       req.req_col.value('Email[1]','VARCHAR(100)')  AS Email,
       req.req_col.value('ProductName[1]','VARCHAR(100)')    AS ProductName,
       req.req_col.value('ProductType[1]','VARCHAR(100)')    AS ProductType,
       v.CustName,
       v.CreatedDate,
       v.BillingCode
FROM @xmlvalue.nodes('/Request')                                req(req_col)
CROSS APPLY  ( SELECT *
                FROM (SELECT req.req_col.value('Name[1]','VARCHAR(100)')     AS Name,
                           req.req_col.value('Value[1]','VARCHAR(100)')      AS Value
                      FROM @xmlvalue.nodes('/Request/Attributes/Attribute') req(req_col)
                     ) tab1
                PIVOT (
                MAX(Value) FOR Name IN ( CustName, CreatedDate, BillingCode )) Tab2
           ) v

没有必要为此使用 PIVOT,您可以在 XPath 表达式中使用过滤器来 select 各种属性 Name-Value 元素对,例如:

with xmlnamespaces (
  'http://testtarget.com/wsdl/myAPI' as anything
)
select
  request.value(N'(AccountId/text())[1]', N'nvarchar(50)') as AccountId,
  request.value(N'(Email/text())[1]', N'nvarchar(50)') as Email,
  request.value(N'(Attributes/Attribute[anything:Name/text()="CustName"]/anything:Value/text())[1]', N'nvarchar(50)') as CustName,
  request.value(N'(Attributes/Attribute[anything:Name/text()="CreatedDate"]/anything:Value/text())[1]', N'nvarchar(50)') as CreatedDate,
  request.value(N'(Attributes/Attribute[anything:Name/text()="BillingCode"]/anything:Value/text())[1]', N'nvarchar(50)') as BillingCode,
  request.value(N'(ProductName/text())[1]', N'nvarchar(50)') as ProductName,
  request.value(N'(ProductType/text())[1]', N'nvarchar(50)') as ProductType
from @xmlvalue.nodes('/Request') foo(request);
AccountId Email CustName CreatedDate BillingCode ProductName ProductType
16000 test@gmail.com TestName 3/26/2022 testbiling TestProduct Recurring