Удалить различные уровни пустых тегов 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())]
Другие вопросы по тегам