4

我正在使用FOR XML PATHSQL Server 2008R2 中的表构造 XML。XML 必须按如下方式构造:

<Root>
    <OuterElement>
        <NumberNode>1</NumberNode>
        <FormattedNumberNode>0001</KFormattedNumberNode>
        <InnerContainerElement>
            <InnerNodeOne>0240</InnerNodeOne>
            <InnerNodeStartDate>201201</InnerNodeStartDate>
        </InnerContainerElement>
    </OuterElement>
</Root>

根据模式文件,InnerContainerElement是可选的,而InnerNodeOne是必需的。架构文件不是我设置的,非常复杂,相互引用并且没有明确的 XSD 命名空间,因此我无法轻松地将它们加载到数据库中。

XML 必须从使用以下查询填充的表中创建:

SELECT
    1 AS NumberNode
    , '0001' AS [FormattedNumberNode]
    , '0240' AS [InnerNodeOne]
    , '201201' AS [InnerNodeStartDate]
INTO #temporaryXMLStore
UNION
SELECT
    2 AS NumberNode
    , '0001' AS [FormattedNumberNode]
    , NULL AS [InnerNodeOne]
    , NULL AS [InnerNodeStartDate]

我可以想到两种使用FOR XML PATH.

1) 使用“InnerContainerElement”作为 XML 子查询的命名结果:

SELECT
    NumberNode
    , [FormattedNumberNode]
    , (
        SELECT
            [InnerNodeOne]
            , [InnerNodeStartDate]
        FOR XML PATH(''), TYPE
    ) AS [InnerContainerElement]
FROM #temporaryXMLStore
FOR XML PATH('OuterElement'), ROOT('Root') TYPE

2) 使用“InnerContainerElement”作为 XML 子查询的输出元素,但不命名:

SELECT
    NumberNode
    , [FormattedNumberNode]
    , (
        SELECT
            [InnerNodeOne]
            , [InnerNodeStartDate]
        FOR XML PATH('InnerContainerElement'), TYPE
    )
FROM #temporaryXMLStore
FOR XML PATH('OuterElement'), ROOT('Root'), TYPE

但是,它们都没有给出期望的结果:在这两种情况下,结果看起来像

<Root>
  <OuterElement>
    <NumberNode>1</NumberNode>
    <FormattedNumberNode>0001</FormattedNumberNode>
    <InnerContainerElement>
      <InnerNodeOne>0240</InnerNodeOne>
      <InnerNodeStartDate>201201</InnerNodeStartDate>
    </InnerContainerElement>
  </OuterElement>
  <OuterElement>
    <NumberNode>2</NumberNode>
    <FormattedNumberNode>0001</FormattedNumberNode>
    <InnerContainerElement></InnerContainerElement>
    <!-- Or, when using the second codeblock: <InnerContainerElement /> -->
  </OuterElement>
</Root>

每当InnerContainerElement为空时,它仍然显示为空元素。根据架构,这是无效的:只要元素InnerContainerElement在 XML 中,InnerNodeOne也是必需的。

我如何构建我的FOR XML PATH查询,InnerContainerElement只要它是空的就会被忽略?

4

1 回答 1

6

InnerContainerElement在没有内容的情况下,您需要确保0 行。

select T.NumberNode,
       T.FormattedNumberNode,
       (
         select T.InnerNodeOne,
                T.InnerNodeStartDate
         where T.InnerNodeOne is not null or
               T.InnerNodeStartDate is not null
         for xml path('InnerContainerElement'), type
       )
from #temporaryXMLStore as T
for xml path('OuterElement'), root('Root')

或者,您可以将元素指定InnerContainerElement为列别名的一部分。

select T.NumberNode,
       T.FormattedNumberNode,
       T.InnerNodeOne as 'InnerContainerElement/InnerNodeOne',
       T.InnerNodeStartDate as 'InnerContainerElement/InnerNodeStartDate'
from #temporaryXMLStore as T
for xml path('OuterElement'), root('Root')
于 2012-11-20T10:20:32.410 回答