【问题标题】:T-SQL: Adding namespaces to XMLT-SQL:向 XML 添加命名空间
【发布时间】:2017-06-09 19:56:24
【问题描述】:

我正在创建 T-SQL 代码来检索 XML 格式的信息。

下面显示了 T-SQL 代码的当前输出:

<ReportingGroup>
  <AccountReport>
    <AccountNumber>12312334</AccountNumber>
    <AccountClosed>false</AccountClosed>
    <AccountHolder>
      <Individual>
        <ResCountryCode>USA</ResCountryCode>
        <TIN>23423545</TIN>
        <Name>
          <FirstName>John</FirstName>
          <LastName>Doe</LastName>
        </Name>
        <Address>
          <CountryCode>USA</CountryCode>
          <AddressFix>
            <Street>112323 ljlkjlkyoid</Street>
            <BuildingIdentifier>NULL</BuildingIdentifier>
            <PostCode>NULL</PostCode>
            <City>USA</City>
          </AddressFix>
          <AddressFree>NULL</AddressFree>
        </Address>
        <BirthInfo />
      </Individual>
    </AccountHolder>
    <FINAL_BALANCE_USD></FINAL_BALANCE_USD>
    <NAME_TEXT>John Doe</NAME_TEXT>
    <NAME_ADDR_TEXT>87 ljhadliwhdlahd</NAME_ADDR_TEXT>
    <NAME_CITY>U.S.A.</NAME_CITY>
  </AccountReport>
</ReportingGroup>

如何修改 T-SQL 以在 xml 标记中添加 ftc: 和 sfc:,如下面的输出?

SELECT
AccountNumber
, AccountClosed
, (
    SELECT --level 2
    ResCountryCode
    , TIN
    , (
        SELECT --level 3
        FirstName
        LastName
        for xml path('Name'), TYPE

       )
     , (
        SELECT --level 3
        CountryCode
        ,(
            SELECT --LEVEL 4
            Street
            , BuildingIdentifier
            , PostCode
            , City
            for xml path('AddressFix'), TYPE
        )
        , AddressFree
        for xml path('Address'), TYPE
       )

     , (
        SELECT --level 3
        BirthDate
        for xml path('BirthInfo'), TYPE
        )
    for xml path('Individual'),  root('AccountHolder'), TYPE
  )
From test_table
for xml path('AccountReport'), root('ReportingGroup')

输出:

 <ftc:ReportingGroup>
      <ftc:AccountReport>
        <ftc:AccountNumber>12312334</ftc:AccountNumber>
        <ftc:AccountClosed>false</ftc:AccountClosed>
        <ftc:AccountHolder>
          <ftc:Individual>
            <sfa:ResCountryCode>USA</sfa:ResCountryCode>
            <sfa:TIN>23423545</sfa:TIN>
            <sfa:Name>
              <sfa:FirstName>John</sfa:FirstName>
              <sfa:LastName>Doe</sfa:LastName>
            </sfa:Name>
            <sfa:Address>
              <sfa:CountryCode>USA</sfa:CountryCode>
              <sfa:AddressFix>
                <sfa:Street>112323 ljlkjlkyoid</sfa:Street>
                <sfa:BuildingIdentifier>NULL</sfa:BuildingIdentifier>
                <sfa:PostCode>NULL</sfa:PostCode>
                <sfa:City>USA</sfa:City>
              </sfa:AddressFix>
              <sfa:AddressFree>NULL</sfa:AddressFree>
            </sfa:Address>
          </ftc:Individual>
        </ftc:AccountHolder>
        <ftc:FINAL_BALANCE_USD></ftc:FINAL_BALANCE_USD>
        <ftc:NAME_TEXT>John Doe</ftc:NAME_TEXT>
        <ftc:NAME_ADDR_TEXT>87 ljhadliwhdlahd</ftc:NAME_ADDR_TEXT>
        <ftc:NAME_CITY>U.S.A.</ftc:NAME_CITY>
      </ftc:AccountReport>
    </ftc:ReportingGroup>

【问题讨论】:

  • 只是作为一个提示:你的输出是无效的......如果你想使用命名空间前缀,这些命名空间必须声明......
  • 您好,感谢您的回答。请注意,我还没有测试发布的答案,我今天会。

标签: sql-server xml tsql xpath namespaces


【解决方案1】:

如果没有 1:n 数据,则不需要嵌套的 SELECTs。试试这样

样机缩短为一些示例性字段

DECLARE @account TABLE(AccountNumber INT,AccountClosed BIT);
DECLARE @holder TABLE(AccountNumber INT,FirstName VARCHAR(100),LastName VARCHAR(100),Street VARCHAR(100));

INSERT INTO @account VALUES(123,0);
INSERT INTO @holder VALUES(123,'Jim','Baker','Bakerstreet 1');

WITH XMLNAMESPACES('SomeFtcUri' AS ftc
                  ,'SomeSfaUri' AS sfa)
SELECT a.AccountNumber AS [ftc:AccountNumber]
      ,a.AccountClosed AS [ftc:AccountClosed]
      ,h.FirstName AS [sfa:AccountHolder/sfa:Individual/sfa:Name/sfa:FirstName]
      ,h.LastName AS [sfa:AccountHolder/sfa:Individual/sfa:Name/sfa:LastName]
      ,h.Street AS [sfa:AccountHolder/sfa:Individual/sfa:Address/sfa:AddressFix/sfa:Street]
FROM @account AS a
INNER JOIN @holder AS h ON a.AccountNumber=h.AccountNumber
FOR XML PATH('ftc:AccountReport'),ROOT('ftc:ReportingGroup'); 

结果

<ftc:ReportingGroup xmlns:sfa="SomeSfaUri" xmlns:ftc="SomeFtcUri">
  <ftc:AccountReport>
    <ftc:AccountNumber>123</ftc:AccountNumber>
    <ftc:AccountClosed>0</ftc:AccountClosed>
    <sfa:AccountHolder>
      <sfa:Individual>
        <sfa:Name>
          <sfa:FirstName>Jim</sfa:FirstName>
          <sfa:LastName>Baker</sfa:LastName>
        </sfa:Name>
        <sfa:Address>
          <sfa:AddressFix>
            <sfa:Street>Bakerstreet 1</sfa:Street>
          </sfa:AddressFix>
        </sfa:Address>
      </sfa:Individual>
    </sfa:AccountHolder>
  </ftc:AccountReport>
</ftc:ReportingGroup>

【讨论】:

  • 这很完美!另一个问题我如何把属性 currCode="USD" 像: 200
  • @Rocklee 只需添加带有@ 字符的属性,例如'USD' AS ftc:AccountBalance/@currCode。这必须放在之前元素本身...
【解决方案2】:

您可能需要像这样添加命名空间:

WITH XMLNAMESPACES ('uri' as ftc)  
SELECT
AccountNumber
, AccountClosed
, (
    SELECT --level 2
    ResCountryCode
    , TIN
    , (
        SELECT --level 3
        FirstName
        LastName
        for xml path('Name'), TYPE

       )
     , (
        SELECT --level 3
        CountryCode
        ,(
            SELECT --LEVEL 4
            Street
            , BuildingIdentifier
            , PostCode
            , City
            for xml path('AddressFix'), TYPE
        )
        , AddressFree
        for xml path('Address'), TYPE
       )

     , (
        SELECT --level 3
        BirthDate
        for xml path('BirthInfo'), TYPE
        )
    for xml path('Individual'),  root('AccountHolder'), TYPE
  )
From test_table
for xml path('AccountReport'), root('ReportingGroup')

【讨论】:

  • 嗨,我起初尝试过,但它只将 ftc: 放在主要的外部标签周围,例如: 。我想像上面显示的输出示例一样添加它们。
  • 好的,因为您有嵌套的电子邮件。然后,您可以在每个 select ... for xml 之前添加命名空间
  • 您的回答根本没有回答问题。添加命名空间声明不会将所需的前缀放在正确的位置...
猜你喜欢
  • 2013-12-25
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多