简体   繁体   English

如何使用 SQL Server 2016 删除 XML 子节点

[英]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.

相关问题 如何使用sql server在XML文档中获取包含给定值的子节点的节点? - How do you get a node that contains a child node with a given value in an XML document using sql server? 如何使用sql server在XML文档中获得包含具有给定属性值的子节点的节点? - How do you get a node that contains a child node with a given attribute value in an XML document using sql server? 在 SQL Server 2016 中将 GROUP BY 与 FOR XML PATH 结合使用 - Using GROUP BY with FOR XML PATH in SQL Server 2016 SQL Server:如何通过sql变量删除xml节点? - SQL Server: how to delete xml node by sql variable? SQL Server:使用xquery时如何检查xml中是否存在子节点 - SQL Server: How to check child node exist or not in xml when using xquery 在SQL Server中获取特定的XML子节点 - Get specific XML Child node in SQL Server 从 SQL Server 2008 中删除 XML 节点 - Delete XML node from in SQL Server 2008 如何在 SQL 服务器中使用 XML DML 更新 XML 节点 - How to update XML node using XML DML in SQL Server 使用SQL Server解析XML文件,并将子节点部分作为XML返回 - Parse XML file using SQL Server, and return child node section as XML 在 SQL Server 2016 上使用 STUFF 和 XML PATH 时如何返回空白或 null 记录? - How to return blank or null record when using STUFF and XML PATH on SQL Server 2016?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM