2014-09-02 79 views
1

我正在使用FOR XML EXPLICIT联合将一些SQL表信息转换为XML文件。这一切都有效,但是我在结果中有各种不同层次的空标签。我想删除所有空标签,但保留每个组的最高级别。下面是这类事情的一个例子,我的意思是:在SQL Server中删除不同级别的空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> 

在这个例子中,只有“不管”的标签,但在真实的数据,可能会有几个反复,所有与不同层次的信息,由根标签包围或同等学历。

任何帮助非常感谢!

谢谢, 马克

回答

3

你可以定义你的“空”版本不包含任何后代属性或文本节点,而不是作为不包含任何后代节点。然后通过只选择其子女的后代保留<Whatever>的子女:

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

嗨,谢谢你的回答;你能澄清一下脚本的实际内容是什么样的吗?对不起,我之前没有使用过xquery - 你稍微留下了我! – 2014-09-02 16:34:42

+0

@HighPlainsGrifter这就是'delete'后面的XPath,代替'// * [not(node())]''。你只需要执行一次。 – wst 2014-09-02 16:45:43

+0

Gotcha - 我试过了,它给出了一个错误,告诉我XQuery语法的'attribute()'不被支持,所以我想我必须做错了什么。但是,我特别没有在XML中使用属性,所以没关系;我删除了这一点离开“SET @ XML.modify('delete/Whatever/* // * [empty(.// text())]')”,它完美地工作。谢谢您的帮助! – 2014-09-02 17:28:35