Удалить различные уровни пустых тегов XML в SQL Server
Я использую 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", но в "полетах" все еще есть уровни пустых узлов. Я мог бы повторять одну и ту же команду изменения снова и снова для каждого уровня, чтобы добраться до точки, где отображаются только "Полеты", но при этом будет удален пустой заполнитель "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>
В этом примере есть только тег "Безотносительно", но в реальных данных их может быть несколько, повторяющихся, с разными уровнями информации, охватываемыми корневым тегом или его эквивалентом.
Любая помощь высоко ценится!
Спасибо Марк
1 ответ
Вы можете определить свою версию "пустого" как не содержащую каких-либо атрибутов-потомков или текстовых узлов, вместо того, чтобы не содержать никаких дочерних узлов. Затем оставьте детей <Whatever>
выбрав только потомков своих детей:
/Whatever/*//*[empty(.//text() | .//attribute())]