【问题标题】:Root element with header and detail rows具有标题行和详细信息行的根元素
【发布时间】:2016-10-09 18:55:28
【问题描述】:

我使用 for xml 选择来生成一个 xml 文件。 我希望有两个根节点,其中包含一些标题标签,然后详细说明表查询结果的行。

例子:

<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 及其数据无关紧要,因为最终选择中的所有标签都是正确的,都针对 xsd 模式进行了验证。 FileHeader 和 Header 标记由变量给出的值填充,因此此处不使用表。

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

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

;WITH XMLNAMESPACES ('url' as xmlns)

谢谢!

【问题讨论】:

  • 也许我遗漏了一些东西,但我不知道您的最终 XML 应该是什么样子...您提供的 XML 在 Jobs/Body 路径中没有 Header 标记。请发布预期输出的示例。

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


【解决方案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>

【讨论】:

  • 这正是我想要的。我没有想过使用 XML 变量来简化我的生活。 xmlnamespace 也很完美。谢谢! (再一次!)
  • @NotApplicable,不知道...固定值...)
  • 在您的示例中,我想在消息标签中添加一个 xmlnamespace。除此之外,你所做的例子是完美的。生成的 xml 正是我想要的形式。
  • @NotApplicable,我的 XML 没有 &lt;Body&gt; 元素...您需要 &lt;ListItem&gt; 处的 xmlns &lt;Message&gt; 处的 xmlns 吗?外面就够了……
  • 我按照您的示例并使用变量将其插入到带有所需 xmlns 的最终查询中,所以我现在很完美。我认为外部就足够了,但 xsd 架构需要它。再次感谢!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多