【问题标题】:Build New XML From Stored XML Value从存储的 XML 值构建新的 XML
【发布时间】:2025-12-04 14:55:01
【问题描述】:

我们存储了相当大的 XML blob(在 XML 类型的列中),我正在进行一个 skunkworks 项目,以尝试在需要时动态构建 XML 的子集。

假设我将这个 XML blob 存储在我们的数据库表中的给定列中:

<root>
    <header>
        <id>1</id>
        <name id="foo">Name</name>
    </header>
    <body>
        <items>
            <addItem>
                <val>1</val>
            </addItem>
            <observeItem>
                <val>2</val>
            </observeItem>
        </items>
    </body>
</root>

我想得到的是,这基本上是重新创建上述文档结构,但只包含items 孩子之一,例如:

<root>
    <header>
        <id>1</id>
        <name id="foo">Name</name>
    </header>
    <body>
        <items>
            <observeItem>
                <val>2</val>
            </observeItem>
        </items>
    </body>
</root>

如果我只对 observeItem 记录感兴趣(items 元素可以有任意数量的子元素,但我只会对其中一个感兴趣)。

我知道我可以执行SELECT @XML.query('//items/child::*[2]') 之类的操作来仅获取给定的子项,但是如何在仅包含其中一个子项的查询中构建完整的原始文档?

【问题讨论】:

  • 你不能从结构中删除 子项吗?还是你需要它更有活力?
  • @MasterYoda 需要更加动态,在实践中,我可能会为每个children 构建这个结构。整个努力只是为了支持一种边缘情况,即某些东西会从我们的缓存中掉出来,我们必须动态构建这个“项目”特定结构以用于报告目的。

标签: sql sql-server xml xpath


【解决方案1】:

我想出了一个解决方案,但我并不完全满意:

DECLARE @XML XML = '
    <root>
        <header>
            <id>1</id>
            <name id="foo">Name</name>
        </header>
        <body>
            <items>
                <addItem>
                    <val>1</val>
                </addItem>
                <observeItem>
                    <val>2</val>
                </observeItem>
            </items>
        </body>
    </root>'


DECLARE @NthChild INT = 2

SELECT
    @XML.query('//header'),
    @XML.query('//items/child::*[sql:variable("@NthChild")]') AS 'items'
FOR XML PATH('root')

我不喜欢明确指定rootitems,但我认为这种方法可以解决问题。

【讨论】: