使用 SQL 将 html 数据读取为 XML
Posted
技术标签:
【中文标题】使用 SQL 将 html 数据读取为 XML【英文标题】:Using SQL read html data as XML 【发布时间】:2018-08-29 16:32:16 【问题描述】:我必须将 html 表格数据读取为 XML。但我无法获得所需格式的所有信息。
declare @xml xml='<body bgcolor="#FFFFFF">
<div id="Edit01" style="position:absolute; left:5px; top:4px; width:462px; height:196px; z-index:1">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="5" >
<span class="auditnoteheader">Charges: </span>
</td>
</tr>
<tr>
<td colspan="5" >
<span class="AuditNoteText">Submitted by ELSGH </span>
</td>
</tr>
<tr>
<td colspan="5" >
<span class="AuditNoteText">Jul 20 2018 9:15PM Eastern Standard Time</span>
</td>
</tr>
<tr class="AuditNoteSubHeader">
<td />
<td valign="top">Charge</td>
<td valign="top">Old Charge Status</td>
<td valign="top">New Charge Status</td>
</tr>
<tr class="AuditNoteText">
<td />
<td valign="top">
<font color="009900">99214 OFFICE OUTPATIENT VISIT 25 MINUTES</font>
</td>
<td valign="top">
<font color="009900">Review</font>
</td>
<td valign="top">
<font color="009900">Submitted</font>
</td>
</tr>
<tr class="AuditNoteText">
<td />
<td valign="top">
<font color="009900">36415 COLLECTION VENOUS BLOOD</font>
</td>
<td valign="top">
<font color="009900">Review</font>
</td>
<td valign="top">
<font color="009900">Submitted</font>
</td>
</tr>
<tr class="AuditNoteSeparater">
<td colspan="5" >
--------------------------------------------------------------------------------------------
</td>
</tr>
</table>
</div>
</body>'
我正在尝试使用此查询。
SELECT TR.AT1.query('data(span)') ,TR.AT1.query('*') ,TR.AT1.value('.','varchar(max)')
FROM @xml.nodes('/body/div/table') as T(N)
cross apply T.N.nodes('./tr/td') as TR(AT1)
cross apply TR.AT1.nodes('.') as para(p1)
在正文标签内,我得到了多个表格。前 3 个标签(可以不同)是表信息。带有 class="AuditNoteSubHeader" 的下一行是表头,之后 class="AuditNoteText" 包含表数据。我需要提取所有信息。有人可以帮忙吗?
我的预期输出是:
对于 AuditNoteText,我得到了多行,所以为了区分它,我给出了 AuditNoteText1、AuditNoteText2 等数字。
【问题讨论】:
【参考方案1】:您的预期输出在我看来并不是最好的格式。如果这不是外部需求,您可以尝试以下方法:
;WITH AllTr AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowIndex
,tr.value('@class','nvarchar(max)') AS trClass
,tr.query('.') AS trNode
FROM @xml.nodes('//table/tr') A(tr)
)
,AllTd AS
(
SELECT AllTr.*
,ROW_NUMBER() OVER(PARTITION BY RowIndex ORDER BY (SELECT NULL)) AS ColumnIndex
,td.value('(.//*/@class)[1]','nvarchar(max)') AS tdClass
,td.value('(.//text())[1]','nvarchar(max)') AS tdText
FROM AllTr
OUTER APPLY trNode.nodes('tr/td[.//text()]') A(td)
)
SELECT RowIndex
,ColumnIndex
,trClass
,tdClass
,tdText
FROM AllTd;
这将提供一个行计数器和一个分区列计数器。这可能比 name numbered 类名更好。
【讨论】:
【参考方案2】:;WITH C1 AS (
SELECT ISNULL(T.N.value('@class', 'varchar(50)'), TR1.AT1.value('@class', 'varchar(50)')) Hdr
, CONVERT(VARCHAR, DENSE_RANK() OVER ( PARTITION BY TR1.AT1 ORDER BY N )-1) AS HdrNum
, TR.AT1.value('.', 'varchar(max)') AS Data
FROM @xml.nodes('/body/div/table/tr,/body/div/table/tr/td/span') AS T ( N )
CROSS APPLY T.N.nodes('./td') AS TR ( AT1 )
OUTER APPLY T.N.nodes('./td/span') AS TR1 ( AT1 )
WHERE TR.AT1.value('.', 'varchar(max)') NOT LIKE '%---%'
AND TR.AT1.value('.', 'varchar(max)') <> ''
)
SELECT Hdr + CASE WHEN HdrNum = '0' THEN '' ELSE HdrNum END AS Hdr
, Data
FROM C1 ORDER BY hdr
【讨论】:
以上是关于使用 SQL 将 html 数据读取为 XML的主要内容,如果未能解决你的问题,请参考以下文章
用于将 XML 数据转换为 html 文件的 C# 与 XSLT [关闭]