SQL Server解析XML空属性

SQL Server解析XML空属性,xml,sql-server-2008,tsql,xquery,Xml,Sql Server 2008,Tsql,Xquery,我正在尝试通过TSQL解析/分解sql server 2008中的XML,其中一个节点具有以下格式的空白属性,没有指定值。我似乎无法检索该值,它会抛出所有其他列 以下是tsql代码和错误的图片: declare @doc nvarchar(4000) set @doc = ' <Objects> <Object> <Property Name="Path">some path</Property> <Property

我正在尝试通过TSQL解析/分解sql server 2008中的XML,其中一个节点具有以下格式的空白属性,没有指定值。我似乎无法检索该值,它会抛出所有其他列

以下是tsql代码和错误的图片:

declare @doc nvarchar(4000)

set @doc = ' 
<Objects>
  <Object>
    <Property Name="Path">some path</Property>
    <Property Name="InstanceName">some instance</Property>
    <Property Name="result1">0.390630000000003</Property>
    <Property Name="result2">63345649697265</Property>
  </Object>
  <Object>
    <Property Name="Path">another path</Property>
    <Property Name="InstanceName" />
    <Property Name="result1">100</Property>
    <Property Name="result2">1002</Property>
  </Object>
 </Objects>
'
  SELECT 
 item.ref.value('(Property/text())[1]', 'nvarchar(128)') AS Path, 
 item.ref.value('(Property/text())[2]', 'nvarchar(128)') AS InstanceName,
 item.ref.value('(Property/text())[3]', 'nvarchar(128)') AS result1,
 item.ref.value('(Property/text())[4]', 'nvarchar(128)') AS result2
  FROM (SELECT CAST(@doc AS XML) AS feedXml) feeds(feedXml) 
   CROSS APPLY feedXml.nodes('/Objects/Object') AS item(ref)
运行查询时,请注意,列InstanceName中填充的是另一列的值,而不是空白、空或null


非常感谢您的帮助。

您需要使用Name属性来引用这些元素,而不仅仅是索引

试试这个:

SELECT
    item.ref.value('(Property[@Name="Path"]/text())[1]', 'nvarchar(128)') AS Path,
    item.ref.value('(Property[@Name="InstanceName"]/text())[1]', 'nvarchar(128)') AS InstanceName,
    item.ref.value('(Property[@Name="result1"]/text())[1]', 'nvarchar(128)') AS result1,
    item.ref.value('(Property[@Name="result2"]/text())[1]', 'nvarchar(128)') AS result2
FROM 
    (SELECT CAST(@doc AS XML) AS feedXml) feeds(feedXml) 
CROSS APPLY 
    feedXml.nodes('/Objects/Object') AS item(ref)

这样,您应该将第二个InstanceName设置为NULL。

在括号内指定所需的节点,因此[4]表示您需要第四行。您使用的XPath表达式是Property/text,这意味着“Property/text[4]”将为您提供第四个文本值。第二个对象只有三个文本值,这就是禁用这些值的原因。 相反,您可以指定希望从第四个属性节点“Property[4]/text[1]”中获取第一个文本值

完整查询可能如下所示:

SELECT 
 item.ref.value('(Property[1]/text())[1]', 'nvarchar(128)') AS Path, 
 item.ref.value('(Property[2]/text())[1]', 'nvarchar(128)') AS InstanceName,
 item.ref.value('(Property[3]/text())[1]', 'nvarchar(128)') AS result1,
 item.ref.value('(Property[4]/text())[1]', 'nvarchar(128)') AS result2
  FROM (SELECT CAST(@doc AS XML) AS feedXml) feeds(feedXml) 
   CROSS APPLY feedXml.nodes('/Objects/Object') AS item(ref)
如果缺少属性节点或节点顺序不一致,上述操作当然仍然会失败。在这种情况下,您应该使用查询