tsql - 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
我该如何解决?
解决方案
像这样尝试:
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。
推荐阅读
- r - R - 将行名转换为向量
- r - 条件绑定 - 根据其他 2 个数据帧中的值创建新数据帧
- javascript - Laravel Vue — 路由器视图不渲染
- antlr4 - ANTLR4 - 从 L 到 R 评估,同等优先级
- azure - 使用网关创建 AKS 群集的权限
- javascript - 在 Heroku 上部署应用程序后,浏览器未收到 JWT cookie
- python - [DRF]:序列化程序中具有相关 ID 的额外字段
- python - 如何在不告诉c位置的情况下向数组添加值
- ios - 在 Testflight 中上传 iPA 失败
- angular - Ionic - Anguler:使用 HttpClient 获取数据