1

我正在尝试通过 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。

任何帮助表示赞赏。

4

2 回答 2

2

您需要<Property>通过使用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)

有了这个,你应该得到你的第二InstanceNameNULL

于 2012-11-12T06:02:25.450 回答
1

在括号内指定您想要的节点,这[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)

如果您缺少属性节点或节点的顺序不一致,上述操作当然仍然会失败。在这种情况下,您应该使用marc_s 提供的查询。

于 2012-11-12T06:32:31.340 回答