首页 > 解决方案 > xml 节点未处理空节点

问题描述

我正在尝试在 SQL Server 2019 中创建一个存储过程,以将 html 解析为节点。我已经设法去除了干扰的 html,但现在我遇到了一个空 td 节点的问题。

这是我用来测试的字符串(注意<td/>):

<table>
    <tr> 
        <td>Element</td>
        <td>20562</td>
        <td>20471</td>
    </tr>
    <tr>
         <td>Other</td>
         <td>No</td>
         <td>Yes</td>
    </tr>
    <tr>
         <td>Other Unique Terms</td>
         <td/>
         <td>Of note:  blah blah. </td>
    </tr>
</table>

这是我的 T-SQL:

DECLARE @data TABLE
        (
               FieldName VARCHAR(MAX),
               OldValue VARCHAR(MAX),
               NewValue VARCHAR(MAX)
        )

DECLARE @html varchar(max), @html2 xml;

SET @html = '<table><tr><td>Element</td><td>20562</td><td>20471</td></tr><tr><td>Other</td><td>No</td><td>Yes</td></tr><tr><td>Other Unique Terms</td><td/><td>Of note:  blah blah. </td></tr></table>';

SET @html2 = CAST(@html as xml);

INSERT INTO @data
    SELECT
        n.value('(./td/text())[1]', 'VARCHAR(MAX)') AS FieldName,
        n.value('(./td/text())[2]', 'VARCHAR(MAX)') AS OldValue,
        n.value('(./td/text())[3]', 'VARCHAR(MAX)') AS NewValue
    FROM 
        @html2.nodes('/table/tr') AS nodes(n) 

SELECT *
FROM @data;

我的结果(最后一行,OldValue应该是 NULL 并且NewValue应该有文本):

FieldName              OldValue                 NewValue
---------------------------------------------------------
Element                20562                    20471
Other                  No                       Yes
Other Unique Terms     Of note:  blah blah.     NULL

我该如何解决?

标签: tsqlsql-server-2019

解决方案


像这样尝试:

SELECT
    n.value('td[1]/text()[1]', 'VARCHAR(MAX)') AS FieldName,
    n.value('td[2]/text()[1]', 'VARCHAR(MAX)') AS OldValue,
    n.value('td[3]/text()[1]', 'VARCHAR(MAX)') AS NewValue
FROM 
    @html2.nodes('/table/tr') AS nodes(n) ;

简而言之:

  • 看起来,好像总是有三个<td>元素。
  • 他们的位置说明了他们的意义
  • 所以我们阅读第一个 <td>并选择它的文本。
  • 然后我们读了第二个……以此类推……
  • final[1]告诉引擎选择第一个text() 节点,它强制执行所需的单例值。

或者你可以试试这个

SELECT
    n.value('td[1]', 'VARCHAR(MAX)') AS FieldName,
    n.value('td[2]', 'VARCHAR(MAX)') AS OldValue,
    n.value('td[3]', 'VARCHAR(MAX)') AS NewValue
FROM 
    @html2.nodes('/table/tr') AS nodes(n) 

在这种情况下,空元素将作为空字符串返回,而不是 NULL。


推荐阅读