将xml解析为表

时间:2015-01-22 17:07:22

标签: sql sql-server xml parsing xml-parsing

我有一些xml,如:

<MyDetails>
  <detail key="key1" value="value1" />
  <detail key="key2" value="value2" />
  <detail key="key3" value="value3" />
  <detail key="key4" value="value4" />
</MyDetails>

我希望能够以两列Key和Value的表格格式解析它。如何通过指定节点路径(即本例中为“/ MyDetails / detail”以及KeyAttributeName和ValueAttributeName)来创建SQL函数来实现此目的。我创建了以下函数,但它给了我错误:

    ALTER FUNCTION [dbo].[GetXmlTable] (
        @XmlSource XML,
        @HierarchyPath NVARCHAR(50) = '',
        @SpecificKey NVARCHAR(255) = NULL,
        @KeyAttributeName NVARCHAR(50) = 'key',
        @ValueAttributeName NVARCHAR(50) = 'value'
        )
    RETURNS @Table TABLE (
        [Key] NVARCHAR(255),
        [Value] NVARCHAR(500)
        )
    AS
    BEGIN

        DECLARE @KeyAttribute NVARCHAR (50) = '@' + @KeyAttributeName
        DECLARE @ValueAttribute NVARCHAR (50) = '@' + @ValueAttributeName
        DECLARE @Path NVARCHAR (50) = '/' + @HierarchyPath

        INSERT INTO @Table
        SELECT XmlElement.Attribute.value(@KeyAttribute, 'nvarchar(255)') AS [Key] 
          ,XmlElement.Attribute.value(@ValueAttribute, 'nvarchar(500)') AS [Value]
        FROM @XmlSource.nodes(@Path) AS XmlElement(Attribute)
        WHERE @SpecificKey IS NULL OR XmlElement.Attribute.value(@KeyAttribute, 'nvarchar(255)') = @SpecificKey

    RETURN
END
GO

错误:

  

Msg 8172,Level 16,State 1,Procedure GetXmlTable,Line 12 The   XML数据类型方法“nodes”的参数1必须是字符串   文字。

想要调用这样的函数:

select * from dbo.GetXmlTable(CAST('<MyDetails>
  <detail key="key1" value="value1" />
  <detail key="key2" value="value2" />
  <detail key="key3" value="value3" />
  <detail key="key4" value="value4" />
</MyDetails>' as XML), 'MyDetails/detail', default, default, default)

UPDATE ---------------

我尝试使用sql变量语法,但返回的表是空白的。你能否指出我可能做错了什么:

DECLARE @KeyAttr VARCHAR(50) = N'@' + @KeyAttributeName
DECLARE @ValueAttr VARCHAR(50) = N'@' + @ValueAttributeName
DECLARE @Path VARCHAR(100) = '/' + @HierarchyPath

    INSERT INTO @Table
    SELECT XmlElement.Attribute.value('(*[local-name() = sql:variable("@KeyAttr")])[1]', 'nvarchar(255)') AS [Key]
          ,XmlElement.Attribute.value('(*[local-name() = sql:variable("@ValueAttr")][1])', 'nvarchar(500)') AS [Value]
    FROM @XmlSource.nodes('(*[local-name() = sql:variable("@Path")])') AS XmlElement(Attribute)
    WHERE @SpecificKey IS NULL OR XmlElement.Attribute.value('(*[local-name() = sql:variable("@KeyAttr")])[1]', 'nvarchar(255)') = @SpecificKey

1 个答案:

答案 0 :(得分:1)

此查询会将您的XML粉碎成一个简单的表格;

declare @xml xml = '<MyDetails>
  <detail key="key1" value="value1" />
  <detail key="key2" value="value2" />
  <detail key="key3" value="value3" />
  <detail key="key4" value="value4" />
</MyDetails>'

select 
    t.c.value('@key', 'varchar(100)') as [key],
    t.c.value('@value', 'varchar(100)') as value
from 
    @xml.nodes('/MyDetails/detail') as t(c)

错误&#34; XML数据类型方法的参数1&#34;节点&#34;必须是字符串文字。&#34;意思是它所说的 - 你不能将变量作为参数传递给nodes()方法。但是,您可以在传递给Nodes()的XQuery中引用变量 - 有关详细信息,请参阅sql:variable()