【问题标题】:Delete empty XML nodes using T-SQL FOR XML PATH使用 T-SQL FOR XML PATH 删除空 XML 节点
【发布时间】:2012-11-20 07:52:57
【问题描述】:

我正在使用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 在空时被忽略?

【问题讨论】:

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


    【解决方案1】:

    对于没有内容的情况,您需要确保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')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2018-09-27
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      相关资源
      最近更新 更多