具有 header 和详细信息行的根元素

Root element with header and detail rows

我使用 for xml select 生成一个 xml 文件。 我想要两个包含一些 header 标记的根节点,然后是 table.

查询结果的详细行

示例:

<Root>
 <FileHeader>

  HEADER ROWS

 </FileHeader>
 <Jobs>
  <Message xmlns="url">
   <Header Destination="1" xmlns="url"/>
   <Body>
     <ListItem xmlns="url">

       DETAIL ROWS FROM SELECT 

     </ListItem>

   </Body>
  </Message>
 </Jobs>
</Root>

我要生成的查询是这个:

WITH XMLNAMESPACES('url')
SELECT(
SELECT   

 HEADER ROWS

FOR XML PATH('FileHeader'),
TYPE),
(SELECT  

         '1'     AS 'Message/Header/@Destination',
         'url'   AS 'Message/Header/@xmlns'

FOR XML PATH(''),
TYPE), 
(SELECT  

 DETAIL ROWS FROM SELECT 

FROM MY_TABLE
FOR XML PATH('Jobs'),ROOT('Body'),   
TYPE      )
FOR XML PATH ('Root') 

MY_table 及其数据无关紧要,因为最终 select 中的所有标签均已根据 xsd 架构进行验证。 FileHeader 和 Header 标签由变量给出的值填充,因此那里没有使用 table。

我在查询的中间部分遗漏了一些东西(第二个 select)。按照我的方式,我不能在 Jobs/Body 路径中包含 Header 标记。

更重要的是,我无法填写xmlns 值。我什至使用了我在某些论坛上发现的以下内容,但仍然无法生成具有 xmlns 属性的格式良好的标签。

;WITH XMLNAMESPACES ('url' as xmlns)

谢谢!

首先要声明的一些事情:

  • 不允许像添加任何其他属性一样添加名称空间xmlns
  • 可以使用 WITH XMLNAMESPACES 添加此默认命名空间。但是 - 在子查询的情况下 - 这个名称空间将被重复插入。这并没有错,但很烦人,它可能会破坏您的 XML 并使其难以阅读...
  • 您可以创建一个嵌套的 XML ad-hoc(内联),或者先准备它然后将其插入到最终查询中。这允许您仅将默认命名空间添加到更深的级别。

我不太清楚您真正在寻找什么,但这可能会为您指明正确的方向:

DECLARE @HeaderData TABLE(SomeValue INT,SomeText VARCHAR(100));
DECLARE @DetailData TABLE(DetailsID INT,DetailText VARCHAR(100));

INSERT INTO @HeaderData VALUES
 (100,'Value 100')
,(200,'Value 200');

INSERT INTO @DetailData VALUES
 (1,'Detail 1')
,(2,'Detail 2');

DECLARE @BodyWithNamespace XML;
WITH XMLNAMESPACES(DEFAULT 'SomeURL_for_Body_default_ns')
SELECT @BodyWithNamespace=
(
    SELECT *
    FROM @DetailData AS dd
    FOR XML PATH('DetailRow'),ROOT('ListItem'),TYPE
);

SELECT(
        SELECT *    
        FROM  @HeaderData AS hd
        FOR XML PATH('HeaderRow'),ROOT('FileHeader'),TYPE
      )
      ,
      (
        SELECT 1 AS [Header/@Destination]
              ,@BodyWithNamespace
        FOR XML PATH('Message'),ROOT('Jobs'),TYPE
      )
FOR XML PATH ('Root') 

结果

<Root>
  <FileHeader>
    <HeaderRow>
      <SomeValue>100</SomeValue>
      <SomeText>Value 100</SomeText>
    </HeaderRow>
    <HeaderRow>
      <SomeValue>200</SomeValue>
      <SomeText>Value 200</SomeText>
    </HeaderRow>
  </FileHeader>
  <Jobs>
    <Message>
      <Header Destination="1" />
      <ListItem xmlns="SomeURL_for_Body_default_ns">
        <DetailRow>
          <DetailsID>1</DetailsID>
          <DetailText>Detail 1</DetailText>
        </DetailRow>
        <DetailRow>
          <DetailsID>2</DetailsID>
          <DetailText>Detail 2</DetailText>
        </DetailRow>
      </ListItem>
    </Message>
  </Jobs>
</Root>