SQL Server中如何删除XML文档内的空Item容器及其父节点?
问题描述
我是职场新人,技术经验尚浅,被这个问题困扰两天了。
原始XML文档如下:
<Tables> <dbo.ES_Connection_Modes> <Item /> </dbo.ES_Connection_Modes> <dbo.ES_Device_Categories> <Item> <LINK>1</LINK> <F_Class>1</F_Class> <N_Code>1</N_Code> <B_Default>1</B_Default> <B_Meter>1</B_Meter> <B_Tranf>0</B_Tranf> <B_Regist>0</B_Regist> <B_Show_InMenu>1</B_Show_InMenu> <N_Project>-1</N_Project> <C_Const>EDC_Meter</C_Const> </Item> </dbo.ES_Device_Categories> <dbo.ES_Indicating_Device_Types> <Item /> </dbo.ES_Indicating_Device_Types> <dbo.ES_Operating_Principles> <Item /> </dbo.ES_Operating_Principles> <dbo.ES_Precission_Classes> <Item> <LINK>7</LINK> <N_Project>687783</N_Project> <C_Name>2,0</C_Name> <C_Const>EPC_20</C_Const> </Item> <Item> <LINK>8</LINK> <N_Project>687783</N_Project> <C_Name>2,5</C_Name> <C_Const>EPC_25</C_Const> </Item> </dbo.ES_Precission_Classes> <dbo.ES_Granularity> <Item /> </dbo.ES_Granularity> </Tables>
需要删除所有包含空Item节点的父容器,最终得到如下XML:
<Tables> <dbo.ES_Device_Categories> <Item> <LINK>1</LINK> <F_Class>1</F_Class> <N_Code>1</N_Code> <B_Default>1</B_Default> <B_Meter>1</B_Meter> <B_Tranf>0</B_Tranf> <B_Regist>0</B_Regist> <B_Show_InMenu>1</B_Show_InMenu> <N_Project>-1</N_Project> <C_Const>EDC_Meter</C_Const> </Item> </dbo.ES_Device_Categories> <dbo.ES_Precission_Classes> <Item> <LINK>7</LINK> <N_Project>687783</N_Project> <C_Name>2,0</C_Name> <C_Const>EPC_20</C_Const> </Item> <Item> <LINK>8</LINK> <N_Project>687783</N_Project> <C_Name>2,5</C_Name> <C_Const>EPC_25</C_Const> </Item> </dbo.ES_Precission_Classes> </Tables>
之前尝试的语句报错:
SET @myDoc.modify('delete /Tables/*[contains(name(), "null")]');
解决方案
你之前的语句筛选逻辑错误,目标节点名称里并没有"null",所以无法匹配到要删除的元素。正确的思路是:删除Tables下所有子元素,这些子元素下的所有Item节点都是空的(无任何子节点和文本内容)。
在SQL Server中,使用以下语句即可实现需求:
SET @myDoc.modify('delete /Tables/*[count(Item/*) = 0 and string(Item) = ""]');
语句说明:
/Tables/*:定位到Tables的所有直接子节点(即dbo.XXX格式的节点)count(Item/*) = 0:判断该子节点下的Item没有任何子元素string(Item) = "":判断Item节点没有文本内容- 两个条件同时满足时,删除对应的父节点
如果空Item节点可能包含空白字符(比如空格、换行),可以将string(Item) = ""替换为normalize-space(Item) = "",确保过滤掉带空白的空节点。
内容的提问来源于stack exchange,提问作者Беляев Руслан
相关产品推荐
相关产品推荐

