我正在使用FOR XML PATH
从SQL 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
构建此XML的两种方法。
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
在空的时候被遗漏?
答案 0 :(得分:4)
如果没有内容,您需要确保InnerContainerElement
的行数为零。
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')