簡體   English   中英

XML - 添加不在根目錄中的命名空間

[英]XML - add a namespace not in root

我需要在具有這種格式的 SQL Server 中構建 XML。 您可以看到第一行有兩個 XMLNAMESPACES,但在 Location 旁邊還有第三個。

<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypes">
  <stuff>
    <Description>blue</Description>
    <Location xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues">
      <d3p1:Code>64</d3p1:Code>
      <d3p1:Description>Balloons</d3p1:Description>
    </Location>
  </stuff>
</arrayofstuff>

這是我到目前為止所擁有的,以及一些示例數據。 看起來第一個查詢中有一個嵌套的 XML 查詢,但我似乎無法第二次使用 WITH 語句,因為它必須是批處理中的第一個命令,所以我不知道該怎么做.

IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('myTable'))
BEGIN;
    DROP TABLE [myTable];
END;
GO

CREATE TABLE [myTable] (
    [myTableID] INTEGER NOT NULL IDENTITY(1, 1),
    [Description] VARCHAR(MAX) NULL,
    [sourceID] INTEGER NOT NULL ,
    [Location] VARCHAR(255) NULL,
    [Code] VARCHAR(255) NULL,
    [Location_Desc] VARCHAR(255) NULL,
    PRIMARY KEY ([myTableID])
);
GO

INSERT INTO myTable([SourceID],[Description],[Location],[Code],[Location_Desc])
VALUES(3,'yellow','Oxford County','64','list'),
(3,'blue','Fraser Lake','64','list'),
(2,'red','San Marcello Pistoiese','64','list'),
(2,'green','Gembloux','64','list'),
(2,'green','Yeongcheon','64','list')

GO

WITH XMLNAMESPACES (default 'http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess', 'http://www.w3.org/2001/XMLSchema-instance' as i )
SELECT 
[sourceID]
,cast(stuff((
 SELECT
[Description] as [Description]
,[Code] AS [Location/Code]
,[Location_Desc] AS [Location/Description]
FROM [myTable] mnbm
where mnbm.[sourceID] = p.[sourceID]
for xml path('stuff'), root ('arrayofstuff')
),1,0,'') as xml) as Ids
from [myTable]  p
group by 
p.[sourceID]

這是我目前的輸出結果:

<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess">
  <stuff>
    <Description>commodo</Description>
    <Location>San Marcello Pistoiese</Location>
  </stuff>
  <stuff>
    <Description>ipsum</Description>
    <Location>Gembloux</Location>
  </stuff>
  <stuff>
    <Description>ipsum</Description>
    <Location>Yeongcheon</Location>
  </stuff>
</arrayofstuff>

為什么xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues"必須出現在 Location 元素上有什么特定的原因嗎? 命名空間可以在 XML 文檔中的任何位置定義,只要它們在被引用之前定義,因此您可以在根元素上將其定義為WITH XMLNAMESPACES一部分,例如:

drop table if exists dbo.myTable;

create table dbo.myTable (
    myTableID integer not null identity(1, 1),
    [Description] varchar(max) null,
    sourceID integer not null,
    [Location] varchar(255) null,
    Code varchar(255) null,
    Location_Desc varchar(255) null,
    primary key (myTableID)
);

insert into dbo.myTable (sourceID,[Description],[Location],Code,Location_Desc)
values (1, 'blue', 'Somewhere', '64', 'Balloons');

with xmlnamespaces (
    default 'http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess',
    'http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues' as d3p1,
    'http://www.w3.org/2001/XMLSchema-instance' as i )
select
    [sourceID],
    cast((
        select
            [Description],
            Code as [Location/d3p1:Code],
            Location_Desc as [Location/d3p1:Description]
        from dbo.myTable mnbm
        where mnbm.sourceID = p.sourceID
        for xml path('stuff'), root('arrayofstuff')
    ) as xml) as Ids
from dbo.myTable p
group by p.sourceID;

其中產生:

<arrayofstuff
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues"
  xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypess">
  <stuff>
    <Description>blue</Description>
    <Location>
      <d3p1:Code>64</d3p1:Code>
      <d3p1:Description>Balloons</d3p1:Description>
    </Location>
  </stuff>
</arrayofstuff>

您可以嘗試基於 XQuery 和 FLWOR 表達式的以下解決方案。

它正在生成與所需輸出完全相同的 XML。

這是一個兩步過程:

  1. 編寫原始 XML。
  2. 根據所需的輸出使用命名空間塑造原始 XML。

SQL

-- DDL and sample data population, start
DECLARE @myTable TABLE
(
    [myTableID] INTEGER NOT NULL IDENTITY(1, 1),
    [Description] VARCHAR(MAX) NULL,
    [sourceID] INTEGER NOT NULL,
    [Location] VARCHAR(255) NULL,
    [Code] VARCHAR(255) NULL,
    [Location_Desc] VARCHAR(255) NULL,
    PRIMARY KEY ([myTableID])
);

INSERT INTO @myTable
(
    [sourceID],
    [Description],
    [Location],
    [Code],
    [Location_Desc]
)
VALUES
(3, 'yellow', 'Oxford County', '64', 'list'),
(3, 'blue', 'Fraser Lake', '64', 'list'),
(2, 'red', 'San Marcello Pistoiese', '64', 'list'),
(2, 'green', 'Gembloux', '64', 'list'),
(2, 'green', 'Yeongcheon', '64', 'list');
-- DDL and sample data population, end

;WITH rs AS
(
    SELECT [sourceID]
        , (SELECT [Description] AS [Description]
            , [Code] AS [Code]
            , [Location_Desc] AS [Location_Desc]
            FROM @myTable AS mnbm
            WHERE mnbm.[sourceID] = p.[sourceID]
            FOR XML PATH('stuff'), TYPE, ROOT('arrayofstuff')
        ) AS Ids
    FROM @myTable AS p
    GROUP BY p.[sourceID]
)
SELECT rs.sourceID, rs.Ids AS [Before]
    , rs.Ids.query('<arrayofstuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://schemas.datacontract.org/2004/07/ACME.Domain.Core.ComplexTypes">
{
    for $x in /*:arrayofstuff/*:stuff
    return <stuff>
        <Description>{data($x/*:Description)}</Description>
        <Location xmlns:d3p1="http://schemas.datacontract.org/2004/07/ACME.Infrastructure.CodeValues">
            <d3p1:Code>{data($x/*:Code)}</d3p1:Code>
            <d3p1:Description>{data($x/*:Location_Desc)}</d3p1:Description>
        </Location>
    </stuff>
}
</arrayofstuff>') AS [After]
FROM rs;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM