[英]How to delete a XML child node using SQL Server 2016
I have the following Xml example snippet taken from a larger file:我从一个较大的文件中提取了以下 Xml 示例片段:
<EntityAttributeValue>
<Value />
<Attribute>
<Id>0</Id>
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
<ProductTypeId xsi:nil="true" />
</EntityAttributeValue>
I am trying to remove the <ProductTypeId>
node using SQL so that the above will look like this:我正在尝试使用 SQL 删除
<ProductTypeId>
节点,以便上面的内容如下所示:
<EntityAttributeValue>
<Value />
<Attribute>
<Id>13</Id>
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
</EntityAttributeValue>
I have used the following to SQL query the XML and isolate the above snippet(first one)我使用以下 SQL 查询 XML 并隔离上述代码段(第一个)
select t.c.query('.') as Attributes
from @XMLData.nodes('/Item/ContentAttributeValues/EntityAttributeValue') t(c)
where t.c.value('(Attribute/Id)[1]','INT') = 0
I have tried我试过了
SET @XMLData.modify('delete (/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)')
to remove all the product ids, but to no avail, any help would be greatly recieved.删除所有产品ID,但无济于事,将大大收到任何帮助。
Cheers干杯
In the XML snippet you have provided, you have a different root.在您提供的 XML 片段中,您有一个不同的根。 So, in order for your
delete
to work, all you need is to adjust the path:因此,为了让您的
delete
工作,您只需要调整路径:
SET @XMLData.modify('delete /EntityAttributeValue/ProductTypeId');
Here is a full example.这是一个完整的例子。 I had to add a namespace to the root to accommodate the
xsi:nil="true"
attribute.我必须向根添加一个命名空间以容纳
xsi:nil="true"
属性。
SQL
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML NOT NULL);
INSERT INTO @tbl (xmldata) VALUES
(N'<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ContentAttributeValues>
<EntityAttributeValue>
<Value/>
<Attribute>
<Id>0</Id>
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
<ProductTypeId xsi:nil="true"/>
</EntityAttributeValue>
<EntityAttributeValue>
<Value/>
<Attribute>
<Id>10</Id>
<Name>Use 7</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999770</AttributeValueId>
<ProductTypeId xsi:nil="true"/>
</EntityAttributeValue>
</ContentAttributeValues>
</Item>');
-- DDL and sample data population, end
UPDATE @tbl
SET xmldata.modify('delete /Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId');
SELECT * FROM @tbl;
Output XML
输出 XML
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ContentAttributeValues>
<EntityAttributeValue>
<Value />
<Attribute>
<Id>0</Id>
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
</EntityAttributeValue>
<EntityAttributeValue>
<Value />
<Attribute>
<Id>10</Id>
<Name>Use 7</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999770</AttributeValueId>
</EntityAttributeValue>
</ContentAttributeValues>
</Item>
From your code I take, that you are searching for the <ProductTypeId>
of the EAV-element, where the <Attribute><Id>
has the value 0
.根据我的代码,您正在搜索 EAV 元素的
<ProductTypeId>
,其中<Attribute><Id>
的值为0
。
Your question is not all clear, but I think you might be looking for this:你的问题不是很清楚,但我认为你可能正在寻找这个:
declare @tbl TABLE(ID INT IDENTITY, YourXml XML);
INSERT INTO @tbl VALUES
(N'<Item xmlns:xsi="blahblah">
<ContentAttributeValues>
<EntityAttributeValue>
<Value />
<Attribute>
<Id>0</Id> <!-- Id value = 0 -->
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
<ProductTypeId xsi:nil="true" />
</EntityAttributeValue>
<EntityAttributeValue>
<Value />
<Attribute>
<Id>1</Id> <!-- Other Id value!!! -->
<Name>Use 3</Name>
<AttributeType>other</AttributeType>
</Attribute>
<AttributeValueId>999998</AttributeValueId>
<ProductTypeId xsi:nil="true" />
</EntityAttributeValue>
</ContentAttributeValues>
</Item>');
UPDATE @tbl SET YourXml.modify(N'delete /Item
/ContentAttributeValues
/EntityAttributeValue[Attribute/Id = 0]
/ProductTypeId');
SELECT * FROM @tbl;
The XPath stands for: Dive into the EAV-element and filter for the element(s), which answer the predicate. XPath 代表:深入 EAV 元素并过滤元素,它回答谓词。 Below this EAV-element find the
<ProductTypeID>
and delete it.在此 EAV 元素下方找到
<ProductTypeID>
并将其删除。
In the result you will find, that the node was deleted only for the first EAV-element, which has Id=0
.在结果中,您会发现,该节点仅被删除了第一个 EAV 元素,它的
Id=0
。
Hi All and thank you for your comments.大家好,感谢您的评论。
apologies for not making my code clear, i thought it was in my head and it was late in the day!很抱歉没有让我的代码清晰,我以为这是在我的脑海里,而且已经很晚了! lol.
哈哈。
The SET @XMLData.modify('delete(/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)')
worked a treat.. I had tried that before but i was getting errors, I know realise that the parentheses after the delete, is kinda key to it working ha! SET @XMLData.modify('delete(/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)')
.. 我以前试过,但我遇到了错误,我知道删除后的括号有点关键到它工作哈! thank you all again!!再次感谢大家!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.