【问题标题】:SQL XML NamespacesSQL XML 命名空间
【发布时间】:2018-01-12 09:18:39
【问题描述】:

我一直在使用sql 查询来生成xml 输出。 我已经设置了WITH XMLNAMESPACES(DEFAULT 'http://schemas.nav.gov.hu/2013/szamla', 'http://www.w3.org/2001/XMLSchema' as xs) 来设置命名空间。

WITH XMLNAMESPACES(DEFAULT 'http://schemas.nav.gov.hu/2013/szamla', 'http://www.w3.org/2001/XMLSchema' as xs)  
SELECT CAST(getdate() as date) AS export_datuma
  ,@noOfResults AS export_szla_db
  ,@fromDate AS kezdo_ido
  ,@toDate AS zaro_ido
  ,@minInvoiceNo AS kezdo_szla_szam
  ,@maxInvoiceNo AS zaro_szla_szam
  ,@transactionXml AS [*]
FOR XML PATH('szamlak');

到目前为止,这工作正常,但在上面的查询中,变量 @transactionXml 已经是 xml 数据类型。所以上面这个查询的输出是这样的:

<szamlak xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.nav.gov.hu/2013/szamla">
  <export_datuma>2018-01-12</export_datuma>
  <export_szla_db>21</export_szla_db>
  <kezdo_ido>2018-01-01</kezdo_ido>
  <zaro_ido>2018-01-12</zaro_ido>
  <kezdo_szla_szam>40003753</kezdo_szla_szam>
  <zaro_szla_szam>70000219</zaro_szla_szam>
  <szamla xmlns="">
    <fejlec>
      <szlasorszam>40003753</szlasorszam>
      <szlatipus>Rechnung</szlatipus>
      <szladatum>2018-01-02</szladatum>
      <teljdatum>2017-12-21</teljdatum>
    </fejlec>
    ...

我现在的问题是,我该如何避免每个 szamla 条目都获得属性 xmlns=""

<szamla xmlns="">

应该是这样的:

<szamla>

提前感谢您的帮助。

【问题讨论】:

    标签: sql sql-server xml namespaces


    【解决方案1】:

    一种方法是简单地将其加载到 xml 变量中,然后从中删除不需要的属性

    例如:

    declare @noOfResults int = 12;
    declare @fromDate date = '2018-01-01';
    declare @toDate date = '2018-01-12';
    declare @minInvoiceNo int = 40003753;
    declare @maxInvoiceNo int = 70000219;
    declare @transactionXml xml = '<szamla>
        <fejlec>
          <szlasorszam>40003753</szlasorszam>
          <szlatipus>Rechnung</szlatipus>
          <szladatum>2018-01-02</szladatum>
          <teljdatum>2017-12-21</teljdatum>
        </fejlec>
    </szamla>';
    
    declare @xml xml;
    
    WITH XMLNAMESPACES (DEFAULT 'http://schemas.nav.gov.hu/2013/szamlas', 'http://www.w3.org/2001/XMLSchema' as xs)
    select @xml = (
        SELECT
        CAST(getdate() as date) AS export_datuma
        ,@noOfResults AS export_szla_db
        ,@fromDate AS kezdo_ido
        ,@toDate AS zaro_ido
        ,@minInvoiceNo AS kezdo_szla_szam
        ,@maxInvoiceNo AS zaro_szla_szam
        ,@transactionXml [*]
        FOR XML PATH('szamlak')
    );
    
    set @xml = cast(replace(cast(@xml as nvarchar(max)),'xmlns=""','') as xml);
    
    select @xml;
    

    返回:

    <szamlak xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.nav.gov.hu/2013/szamlas">
      <export_datuma>2018-01-12</export_datuma>
      <export_szla_db>12</export_szla_db>
      <kezdo_ido>2018-01-01</kezdo_ido>
      <zaro_ido>2018-01-12</zaro_ido>
      <kezdo_szla_szam>40003753</kezdo_szla_szam>
      <zaro_szla_szam>70000219</zaro_szla_szam>
      <szamla>
        <fejlec>
          <szlasorszam>40003753</szlasorszam>
          <szlatipus>Rechnung</szlatipus>
          <szladatum>2018-01-02</szladatum>
          <teljdatum>2017-12-21</teljdatum>
        </fejlec>
      </szamla>
    </szamlak>
    

    【讨论】:

    • 感谢您的回答。是的,这与我发布的答案几乎相同。我可以像在您的解决方案中那样删除xmlns,或者像在我的解决方案中那样添加命名空间。但是还有另一种方法而不将其转换为nvarchar(max)
    • 不确定,我考虑过使用 xml modify,但没有找到如何更改命名空间的方法。不过我注意到了一件奇怪的事情。如果您的 XMLNAMESPACES 中没有 DEFAULT,那么它不会添加不需要的属性。
    • 是的,我知道,但是如何在&lt;szamlak&gt; 标签中添加这个xmlns="http://schemas.nav.gov.hu/2013/szamlas"
    • 在我的结果中,命名空间已经存在。但是,除了使用 XMLNAMESPACES 或 REPLACE 之外,我还没有看到其他方法。
    【解决方案2】:

    我通过将完整的 xml 字符串转换为 nvarchar(max),然后用命名空间替换 &lt;szamlak&gt; 标记,以不推荐的方式解决了这个问题。在输出中,xml 文本被转换回xml 数据类型。我还没有找到更好的解决方案。

    DECLARE @xml nvarchar(max)
    SET @xml = (
            CAST(
                (SELECT 
                    CAST(getdate() as date) AS export_datuma
                    ,@noOfResults AS export_szla_db
                    ,@fromDate AS kezdo_ido
                    ,@toDate AS zaro_ido
                    ,@minInvoiceNo AS kezdo_szla_szam
                    ,@maxInvoiceNo AS zaro_szla_szam
                    ,@transactionXml AS [*]
                FOR XML PATH('szamlak')
                ) as nvarchar(max))
            )
    SET @xml = REPLACE(@xml,'<szamlak>', '<szamlak xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.nav.gov.hu/2013/szamla">')
    SELECT cast(@xml as xml) 
    

    【讨论】: