【问题标题】:Remove Varying levels of empty XML tags in SQL Server删除 SQL Server 中不同级别的空 XML 标记
【发布时间】:2014-09-02 16:05:09
【问题描述】:

我正在使用 FOR XML EXPLICIT 来联合将一些 SQL 表信息转换为 XML 文件。一切正常,但我在结果中有大量空标签,处于各种不同的级别。我想删除所有空标签,但保留每个组的顶层。这是我的意思的一个例子:

使用这个无意义的 XML 示例,我可以使用 .modify xquery 删除底层空节点:

DECLARE @XML XML = 
'<Whatever>
  <GlassesTypes>
      <GlassesType />
  </GlassesTypes>
  <ExpressionOfJoy>
      <FellOver>Y</FellOver>
  </ExpressionOfJoy>
  <Flights>
    <Flight>
      <Bookings>
        <Booking>
          <Segments>
            <Segment />
          </Segments>
        </Booking>
      </Bookings>
    </Flight>
  </Flights>
</Whatever>'

SELECT @XML as Before

SET  @Xml.modify('delete //*[not(node())]');

SELECT @XML AS After

这完全符合我对“GlassesTypes”的要求,但“Flights”中仍有空节点级别。我可以对每个级别重复相同的修改命令,直到只显示“航班”,但这样做会删除“GlassesTypes”空占位符:

DECLARE @XML XML = 
'<Whatever>
  <GlassesTypes>
      <GlassesType />
  </GlassesTypes>
  <ExpressionOfJoy>
      <FellOver>Y</FellOver>
  </ExpressionOfJoy>
  <Flights>
    <Flight>
      <Bookings>
        <Booking>
          <Segments>
            <Segment />
          </Segments>
        </Booking>
      </Bookings>
    </Flight>
  </Flights>
</Whatever>'

SELECT @XML as Before

SET  @Xml.modify('delete //*[not(node())]');
SET  @Xml.modify('delete //*[not(node())]');
SET  @Xml.modify('delete //*[not(node())]');
SET  @Xml.modify('delete //*[not(node())]');
SET  @Xml.modify('delete //*[not(node())]');

SELECT @XML AS After

有没有什么方法可以删除所有空节点,直到倒数第二个空节点,而不管组包含多少级别?理想的结果是这样的:

<Whatever>
  <GlassesTypes />
  <ExpressionOfJoy>
      <FellOver>Y</FellOver>
  </ExpressionOfJoy>
  <Flights />
</Whatever>

在这个例子中,只有“Whatever”标签,但在真实数据中,可能有几个重复的,都具有不同级别的信息,被根标签或等效标签所包含。

非常感谢任何帮助!

谢谢, 标记

【问题讨论】:

    标签: sql sql-server xml xquery xml.modify


    【解决方案1】:

    您可以将您的“空”版本定义为不包含任何后代属性或文本节点,而不是不包含任何后代节点。然后通过仅选择其子代的后代来保留&lt;Whatever&gt; 的子代:

    /Whatever/*//*[empty(.//text() | .//attribute())]
    

    【讨论】:

    • 您好,谢谢您的回答;你能澄清一下实际的脚本行是什么样的吗?对不起,我以前没有用过很多 xquery - 你稍微落后了我!
    • @HighPlainsGrifter 这只是delete 之后的XPath,代替了//*[not(node())]。您应该只需要执行一次。
    • Gotcha - 我试过了,它给出了一个错误,告诉我不支持 XQuery 语法'attribute()',所以我想我一定做错了什么。但是,我特别没有在我的 XML 中使用属性,所以这很好;我已删除该位以保留“SET @XML.modify('delete /Whatever/*//*[empty(.//text())]')”,它可以完美运行。感谢您的帮助!
    • @HighPlainsGrifter 嗯,也许attribute() 是 XSLT 2.0,不确定。如果您需要保留带有属性的元素,您可以尝试将.//attribute() 替换为.//@*,应该会支持。
    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 2010-12-13
    • 2014-12-31
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2019-01-07
    相关资源
    最近更新 更多