2

我从一个较大的文件中获取了以下 Xml 示例片段:

<EntityAttributeValue>
  <Value />
  <Attribute>
    <Id>0</Id>
    <Name>Use 3</Name>
    <AttributeType>other</AttributeType>
  </Attribute>
  <AttributeValueId>999998</AttributeValueId>
  <ProductTypeId xsi:nil="true" />
</EntityAttributeValue>

我正在尝试<ProductTypeId>使用 SQL 删除节点,以便上面的内容如下所示:

<EntityAttributeValue>
  <Value />
  <Attribute>
    <Id>13</Id>
    <Name>Use 3</Name>
    <AttributeType>other</AttributeType>
  </Attribute>
  <AttributeValueId>999998</AttributeValueId>
</EntityAttributeValue>

我使用以下 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

我试过了

SET @XMLData.modify('delete (/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)') 

删除所有产品ID,但无济于事,任何帮助都会得到很大的帮助。

干杯

4

4 回答 4

2

在您提供的 XML 片段中,您有一个不同的根。所以,为了让你delete工作,你只需要调整路径:

SET @XMLData.modify('delete /EntityAttributeValue/ProductTypeId');
于 2020-02-17T15:17:51.887 回答
1

这是一个完整的例子。我必须在根目录中添加一个命名空间来容纳该xsi:nil="true"属性。

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;

输出 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>
于 2020-02-17T15:59:44.933 回答
1

从我的代码中,您正在搜索<ProductTypeId>EAV 元素的 ,其中<Attribute><Id>具有 value 0

您的问题并不完全清楚,但我认为您可能正在寻找这个:

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;

XPath 代表:深入 EAV 元素并过滤元素,这些元素回答谓词。在此 EAV 元素下方找到<ProductTypeID>并删除它。

在结果中,您会发现仅删除了第一个 EAV 元素的节点,该元素具有Id=0.

于 2020-02-17T16:03:55.707 回答
0

大家好,感谢您的评论。

很抱歉没有让我的代码清晰,我以为它在我的脑海里,而且已经很晚了!哈哈。

SET @XMLData.modify('delete(/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)') 是一种享受。我之前曾尝试过,但我遇到了错误,我知道删除后的括号是它工作的关键哈!再次感谢大家!!

于 2020-02-18T08:34:02.060 回答