sql-server - T-SQL 替换 XML 节点

标签 sql-server xml tsql

我想用新节点替换 XML 节点。我正在尝试使其动态化,因此替换节点名称是一个变量

DECLARE @xmlSource AS XML = '<Root><Transactions><ReplaceMe>This information should be gone</ReplaceMe></Transactions></Root>'
DECLARE @xmlInsert AS XML = '<NewNode>New Information</NewNode>'
DECLARE @NodeName NVARCHAR(500) = 'ReplaceMe'

生成的 XML 应该如下所示:

<Root><Transactions><NewNode>New Information</NewNode></Transactions></Root>

最佳答案

没有直接的方法可以用另一个节点替换一个完整的节点。

但是你可以删除它并插入新的:

DECLARE @xmlSource AS XML = '<Root><Transactions><ReplaceMe>This information should be gone</ReplaceMe></Transactions></Root>'
DECLARE @xmlInsert AS XML = '<NewNode>New Information</NewNode>'
DECLARE @NodeName NVARCHAR(500) = 'ReplaceMe'

SET @xmlSource.modify('delete /Root/Transactions/*[local-name(.) eq sql:variable("@NodeName")]');

SELECT @xmlSource; --ReplaceMe is gone...

SET @xmlSource.modify('insert sql:variable("@xmlInsert") into (/Root/Transactions)[1]');

SELECT @xmlSource; 

结果

<Root>
  <Transactions>
    <NewNode>New Information</NewNode>
  </Transactions>
</Root>

更新通用解决方案

根据您的评论,我了解到您对 XML 一无所知,只需要用另一个节点替换您知道名称的一个节点...

这个解决方案是基于字符串的(无论如何都非常丑陋)并且有一些缺陷:

  • 如果有多个节点同名,则只取第一个
  • 如果节点多次存在且内容相同,则两处都替换
  • 如果您的 xml 包含 CDATA 部分,它们将被隐式地转移到正确转义的普通 XML 中。没有语义损失,但这可能会破坏结构验证...

即使是特殊字符,这也应该有效,因为所有的转换都是从 XML 到 NVARCHAR 并返回。转义字符应在两侧保持相同。

否则必须使用递归方法来获取节点的完整路径并动态构建我的第一个语句。这更干净但更重...

DECLARE @xmlSource AS XML = '<Root><Transactions><ReplaceMe>This information should be gone</ReplaceMe></Transactions></Root>'
DECLARE @xmlInsert AS XML = '<NewNode>New Information</NewNode>'
DECLARE @NodeName NVARCHAR(500) = 'ReplaceMe'

SELECT 
CAST( 
REPLACE(CAST(@xmlSource AS NVARCHAR(MAX))
       ,CAST(@xmlSource.query('//*[local-name(.) eq sql:variable("@NodeName")][1]') AS NVARCHAR(MAX))
       ,CAST(@xmlInsert AS NVARCHAR(MAX))
        )
AS XML) 

关于sql-server - T-SQL 替换 XML 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626227/

相关文章:

sql - t-sql 对连续分区或运行进行编号(字段中具有相同值的序列)

python - 如何在 SQLAlchemy 中为 MSSQL 设置架构?

python - 如何使用 elementtree 将元素添加到 xml 文件

xml - 如何优化 XQuery fn :count() in FLWOR (Parallelize)?

javascript - XSLT 分页显示一些计算的节点值以及在下一行检索到的前一行值 (II)

sql - 如何根据列值进行条件连接

sql-server - 带文件名参数的批量插入

sql-server - 有什么办法可以避免子查询吗?

sql-server - 如何从 SQL Server 获取 ROOT 节点名称

sql-server - Python - pyodbc 使用参数名称调用存储过程