删除 SQL Server 中不同级别的空 XML 标记
Posted
技术标签:
【中文标题】删除 SQL Server 中不同级别的空 XML 标记【英文标题】:Remove Varying levels of empty XML tags in SQL Server 【发布时间】: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”标签,但在真实数据中,可能有几个重复的,都具有不同级别的信息,被根标签或等效标签所包含。
非常感谢任何帮助!
谢谢, 标记
【问题讨论】:
【参考方案1】:您可以将您的“空”版本定义为不包含任何后代属性或文本节点,而不是不包含任何后代节点。然后通过仅选择其子代的后代来保留<Whatever>
的子代:
/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()
替换为.//@*
,应该会支持。以上是关于删除 SQL Server 中不同级别的空 XML 标记的主要内容,如果未能解决你的问题,请参考以下文章
sql server 查询 order by 与 union 并替换多个列的空值
Seaborn FacetGrid 包括已删除级别的空列/行
sql server where 字段 is null 的问题