SQL 替换类型化 XML 数据

Posted

技术标签:

【中文标题】SQL 替换类型化 XML 数据【英文标题】:SQL Replace Typed XML Data 【发布时间】:2021-12-12 21:05:30 【问题描述】:

我正在使用将参数的 XML 文档存储为列的第三方软件。我正在尝试编写一个 SQL-Server 脚本来替换下面 XML 中的电子邮件地址。

<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
  <KeyValueOfstringanyType> 
    <Key>Email</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">Michael@dundermifflin.com</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType> 

到目前为止,我得到的最接近的是这个......它运行并说行受到影响但什么也没做。

update t 
set XMLColumn.modify('replace value of (/ArrayOfKeyValueOfstringanyType/KeyValueOfstringanyType/Key/Value/string())[1] with "dwight@staples.com"')

在查看了其他帖子和 Microsoft 的文档 (https://docs.microsoft.com/en-us/sql/t-sql/xml/replace-value-of-xml-dml?view=sql-server-ver15#a-replacing-values-in-an-xml-instance --Item D) 之后,我似乎遗漏了一些关于命名空间的内容。如果我正确理解 XML,则似乎有多个名称空间要声明。在几次尝试都没有成功后,我缺乏 XML 经验让我转向这里。

非常感谢任何帮助!

【问题讨论】:

【参考方案1】:

请尝试以下解决方案。

正如您猜对的那样,罪魁祸首是默认命名空间。

另外,我必须调整 XPath 表达式。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, XMLColumn XML);
INSERT INTO @tbl (XMLColumn) VALUES
(N'<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                                xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <KeyValueOfstringanyType>
        <Key>Email</Key>
        <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema"
               i:type="d3p1:string">Michael@dundermifflin.com</Value>
    </KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>');
-- DDL and sample data population, end

-- before
SELECT * FROM @tbl;

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/2003/10/Serialization/Arrays')
UPDATE @tbl 
SET XMLColumn.modify('replace value of (/ArrayOfKeyValueOfstringanyType/KeyValueOfstringanyType/Value/text())[1] with "dwight@staples.com"');

-- after
SELECT * FROM @tbl;

【讨论】:

啊哈!非常感谢您的帮助! @Ray,很高兴听到建议的解决方案对您有用。请不要忘记将其标记为答案。【参考方案2】:

你必须声明默认命名空间

DECLARE @XML XML = N'<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
  <KeyValueOfstringanyType> 
    <Key>Email</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">Michael@dundermifflin.com</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType> '

set @XML.modify('
declare default element namespace "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; 
replace value of (/ArrayOfKeyValueOfstringanyType/KeyValueOfstringanyType/Value/text())[1] with "dwight@staples.com"')

SELECT @XML

【讨论】:

以上是关于SQL 替换类型化 XML 数据的主要内容,如果未能解决你的问题,请参考以下文章

替换 PL/SQL 中的特殊 XML 字符

用 XML 输出替换 sql 中的文本

sql替换数据库字段中的字符

SQL替换字段最后一个字符和几个字符

sql注入之常见注入类型

如何对sql数据库中的某一字段进行替换?