使用 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的主要内容,如果未能解决你的问题,请参考以下文章

java怎么将数据导出为xml文件

将 HTML 表单数据保存为 XML

用于将 XML 数据转换为 html 文件的 C# 与 XSLT [关闭]

使用 c# asp.net 获取 XML 数据并插入到 sql server

将数据从 XML 文件导入 SQL 数据库

使用vb6通过MSFlexigrid将XML数据导入SQL表