如何在SQL Server 2008中从XML变量中删除属性?

7

我有一个名为XML的表(在SQL Server 2008中),它有一个名为XmlDocument的字段,类型为XML。我正在尝试从XML变量中删除属性。

这是我的xml的样子

<clue_personal_auto xmlns="http://cp.com/rules/client">
  <admin>
     <receipt_date>03/16/2011</receipt_date>
     <date_request_ordered>03/16/2011</date_request_ordered>
     <report_usage>Personal</report_usage>
  </admin>
</clue_personal_auto>

我的查询。
UPDATE XML
SET XmlDocument.modify('delete  (/clue_personal_auto/@xmlns)[1]')
 WHERE xmlid = 357

当我在查询分析器中运行此查询时,我看到消息“1行受影响”,但实际上 clue_personal_auto 元素的 xmlns 属性并没有被删除。你有什么想法我做错了什么。
谢谢 BB

2
(1 行受影响) 只是表示您执行了更新操作。如果有一个时间戳列,它也会改变。就像 update tbl set id=id 也会成功,但什么也不做。 - RichardTheKiwi
请注意,SQL Server 函数 .modify() 使用供应商的 XML 数据修改语言 - user357812
3个回答

7

您需要使用WITH xmlnamespaces,否则"/clue_personal_auto"将无法匹配带有命名空间的clue_personal_auto xmlns="..."节点。

不仅如此,由于命名空间不是普通属性,因此您实际上无法删除它。

以下是删除普通属性的示例:

declare @xml table (xmlid int, xmldocument xml)
insert @xml select 357, '
<clue_personal_auto xmlns="http://cp.com/rules/client" otherattrib="x">
  <admin>
     <receipt_date>03/16/2011</receipt_date>
     <date_request_ordered>03/16/2011</date_request_ordered>
     <report_usage>Personal</report_usage>
  </admin>
</clue_personal_auto>'

;WITH XMLNAMESPACES ('http://cp.com/rules/client' as ns)
UPDATE @XML
SET XmlDocument.modify('delete  (/ns:clue_personal_auto/@otherattrib)[1]')
WHERE xmlid = 357

select * from @xml

6
UPDATE XML
  SET CONVERT(XML, REPLACE(CONVERT(NVARCHAR(MAX), XmlDocument), N' xmlns=...'))
WHERE ID = 357

1
不错 - 暴力破解但有效! - Ed Graham

2
我似乎找不到一个简单的方法来做这件事,但是真正的问题是:为什么你想要移除命名空间?使用WITH XMLNAMESPACES ...结构,您可以轻松地利用命名空间。
与其花费大量精力去摆脱它,不如学习XML命名空间并开始使用它们!
您可以很容易地在查询中使用该XML命名空间:
;WITH XMLNAMESPACES (DEFAULT 'http://cp.com/rules/client' )
SELECT
    XmlDocument.value('(/clue_personal_auto/admin/report_usage)[1]', 'varchar(25)')
FROM XML
WHERE ID = 357

同时,您也可以放心地使用它 - 不再需要人为删除xmlns=声明了!


1
摆脱命名空间的一个原因是它们会破坏许多以前从未使用过它们的遗留代码。在我的应用程序中,命名空间没有任何作用(除了使现有的XPath命令停止工作)。 - Ed Graham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接