代码之家  ›  专栏  ›  技术社区  ›  Jeremy Pridemore

如何使用T-SQL的XML数据类型方法:query在生成的XML中的根元素上设置xmlns属性?

  •  1
  • Jeremy Pridemore  · 技术社区  · 12 年前

    我创建了一个问题的简化版本:

    DECLARE @X XML = 
    '<Root xmlns="TestNS" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Test>
            <Id>1</Id>
            <InnerCollection>
                <InnerItem>
                    <Value>1</Value>
                </InnerItem>
                <InnerItem>
                    <Value>2</Value>
                </InnerItem>
                <InnerItem>
                    <Value>3</Value>
                </InnerItem>
            </InnerCollection>
        </Test>
        <Test>
            <Id>2</Id>
            <InnerCollection>
                <InnerItem>
                    <Value>5</Value>
                </InnerItem>
                <InnerItem>
                    <Value>6</Value>
                </InnerItem>
                <InnerItem>
                    <Value>7</Value>
                </InnerItem>
            </InnerCollection>
        </Test>
    </Root>'
    

    我正在尝试编写一个查询 <Test> 元素,并将其分解为一行。在每一行中,我都希望选择Id和InnerCollection作为XML。我想为第一行(Id:1)创建此InnerCollection XML:

    <InnerCollection xmlns="Reed.Api" xmlnsi="http//www.w3.org/2001/XMLSchema-instance">
      <InnerItem>
        <Value>1</Value>
      </InnerItem>
      <InnerItem>
        <Value>2</Value>
      </InnerItem>
      <InnerItem>
        <Value>3</Value>
      </InnerItem>
    </InnerCollection>
    

    我试着用这个查询来做这件事,但它在元素上放了一个我不想要的命名空间:

    ;WITH XMLNAMESPACES
    (
        DEFAULT 'TestNS'
        , 'http://www.w3.org/2001/XMLSchema-instance' AS i
    )
    SELECT 
        X.value('Id[1]', 'INT') Id
        -- Creates a p1 namespace that I don't want.
        , X.query('InnerCollection') InnerCollection
    FROM @X.nodes('//Test') AS T(X)
    

    我的谷歌功能今天不是很强大,但我想这并没有让这个该死的函数被称为查询变得更容易。我愿意使用查询方法以外的其他方法来创建该XML值。

    我可以使用这种方法:

    ;WITH XMLNAMESPACES
    (
        DEFAULT 'TestNS'
        , 'http://www.w3.org/2001/XMLSchema-instance' AS i
    )
    SELECT 
        X.value('Id[1]', 'INT') Id
        ,CAST(
            (SELECT 
                InnerNodes.Node.value('Value[1]', 'INT') AS 'Value'
            FROM X.nodes('./InnerCollection[1]//InnerItem') AS InnerNodes(Node) 
            FOR XML PATH('InnerItem'), ROOT('InnerCollection')
            ) AS XML) AS InnerCollection
    FROM @X.nodes('//Test') AS T(X)
    

    但这涉及到调用其上的节点,将其分解为可选择的内容,然后使用FOR XML将其重新选择为XML。。。从一开始就是XML。这似乎是一种效率低下的方法,所以我希望这里的人能有更好的想法。

    1 回复  |  直到 12 年前
        1
  •  1
  •   Jeremy Pridemore    12 年前

    以下是如何使用查询方法在我的问题所要查找的每一行上创建XML来执行SELECT的方法:

    ;WITH XMLNAMESPACES
    (
        'http://www.w3.org/2001/XMLSchema-instance' AS i
        , DEFAULT 'TestNS'
    )
    SELECT
        Test.Row.value('Id[1]', 'INT') Id
        , Test.Row.query('<InnerCollection xmlns="TestNS" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">{InnerCollection}</InnerCollection>')
    FROM @X.nodes('/Root/Test') AS Test(Row)