带有标题和详细信息行的根元素

时间:2016-10-09 18:55:29

标签: sql-server xml xml-namespaces for-xml-path

我使用for xml select来生成xml文件。 我希望有两个根节点包含一些标头标签,然后详细说明由表上的查询产生的行。

示例:

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') 

我想要产生的查询就是这个:

;WITH XMLNAMESPACES ('url' as xmlns)

MY_table及其数据无关紧要,因为最终选择中的所有标记都是正确的,并根据xsd模式进行验证。 FileHeader和Header标签使用变量给出的值填充,因此不使用表。

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

更重要的是,我无法用xmlns值填写。我甚至在一些论坛上使用了以下内容,但仍无法使用xmlns属性生成格式良好的标记。

{{1}}

谢谢!

1 个答案:

答案 0 :(得分:1)

首先说明一些事情:

  • 不允许像任何其他属性一样添加名称空间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>