我得到了这样的XML:
<root>
<child1>
<...../>
<...../>
<...../>
<child2>
<child3>Value1</child3>
<child3>Value2</child3>
<child3>Value3</child3>
</child2>
</child1>
</root>
我已经搜索了几天但是找不到我遇到的这个问题的合适答案。
基本上,我想从child1
及其所有子节点中删除root
节点value
(在这种情况下,Value1
){{1}但是,可能有多个child3
个节点,如果它有我想要的值,我想保留child3
(在这种情况下,它可以是child3
或Value2
) ,即使它有一个值(Value3
)我试图删除。
目前,这就是我正在使用的。
Value1
我想做的是
set @xml.modify('delete root/child1[child2[child3 = "Value1"]]')
基本上,不要删除包含我想要的子数据的节点,即使它具有我不想要的特定值,然后删除我不想要的每个节点其他情况。
通过查询set @xml.modify('delete root/child1[child2[child3 = "Value1"] AND !(child2[child3 = "Value2"] OR child2[child3 = "Value3"])]')
节点中的ID
并进行大量预备工作,还有其他方法可以实现此目的,但我希望尽可能整合代码或者拥有比这更智能的代码。有什么想法吗?
答案 0 :(得分:1)
您可以使用XML.modify()方法和contains函数(not(contains..)
):
DECLARE @x xml = N'<root>
<child1>
<child2>
<child3>Value1</child3>
<child3>Value2</child3>
<child3>Value3</child3>
</child2>
</child1>
<child1>
<child2>
<child3>Value1</child3>
<child3>Value4</child3>
<child3>Value5</child3>
</child2>
</child1>
<child1>
<child2>
<child3>Value5</child3>
<child3>Value2</child3>
<child3>Value6</child3>
</child2>
</child1>
</root>'
SET @x.modify('delete /root/child1[contains(.,"Value1") and (not(contains(.,"Value2")) or not(contains(.,"Value3")))]')
SELECT @x
输出将是:
<root>
<child1>
<child2>
<child3>Value1</child3>
<child3>Value2</child3>
<child3>Value3</child3>
</child2>
</child1>
<child1>
<child2>
<child3>Value5</child3>
<child3>Value2</child3>
<child3>Value6</child3>
</child2>
</child1>
</root>
答案 1 :(得分:0)
我不知道,如果我确实得到了这个,但你可以用FLWOR-query()
- 级联来解决这个问题:
DECLARE @xml xml =
N'<root>
<child1 id="1" type="Is to be deleted completely">
<child2>
<child3>Value1</child3>
</child2>
<child2>
<child3>Value1</child3>
</child2>
</child1>
<child1 id="2" type="Should remain but those with the search value should be deleted">
<child2>
<child3>Value1</child3>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
</child1>
<child1 id="3" type="First child2 delete, second just delete the one with delete value, third untouched">
<child2>
<child3>Value1</child3>
</child2>
<child2>
<child3>Value1</child3>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
<child2>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
</child1>
<child1 id="4" type="Untouched, no search value">
<child2>
<child3>Other m</child3>
</child2>
<child2>
<child3>Other n</child3>
</child2>
</child1>
</root>';
DECLARE @DeleteValue NVARCHAR(100)='Value1';
第一个FLWOR-query()将重建XML而不带有带有搜索值的节点
第二个FLWOR-query()将删除所有没有内容的child2元素
第三个FLWOR-query()将删除所有没有内容的child1元素
这是查询:
SELECT @xml.query
(
N'
<root>
{
for $c1 in /root/child1
return
<child1> {$c1/@*}
{
for $c2 in $c1/child2
return
<child2> {$c2/@*}
{
for $c3 in $c2/child3[text()!=sql:variable("@DeleteValue")]
return $c3
}
</child2>
}
</child1>
}
</root>'
).query
(
N'
<root>
{
for $c1 in /root/child1
return
<child1> {$c1/@*}
{
for $c2 in $c1/child2[string-length(.)!=0]
return $c2
}
</child1>
}
</root>'
).query
(
N'
<root>
{
for $c1 in /root/child1[string-length(.)!=0]
return $c1
}
</root>'
);
这是结果
<root>
<child1 id="2" type="Should remain but those with the search value should be deleted">
<child2>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
</child1>
<child1 id="3" type="First child2 delete, second just delete the one with delete value, third untouched">
<child2>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
<child2>
<child3>Other a</child3>
<child3>Other c</child3>
</child2>
</child1>
<child1 id="4" type="Untouched, no search value">
<child2>
<child3>Other m</child3>
</child2>
<child2>
<child3>Other n</child3>
</child2>
</child1>
</root>