如何在 sqlserver 中将 xml 转换为 table 或 html table

How to convert xml as a table or html table in sqlserver

xml 是 sqlserver 中的一种类型,现在我想将一个 table 变量传递给过程,但是您必须将 table 定义为类型(使用“创建类型”) . 所以我想我可以使用 xml 作为变量传递给过程作为参数。

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 
  
)
insert into @tv values(1,'tom','finance'),(2,'mark','business');

declare @xml xml;
set @xml  =(select * from @tv for xml  path('row') ,type )
select @xml  ;

我想像@tv一样使用table作为参数,将它传递给程序, 得到这样的结果:

<table>
<tr><td>1</td><td>tom</td><td>finance</td></tr>
<tr><td>2</td><td>mark</td><td>business</td></tr>
</table>

我知道可以这样做:

select id as td ,username as td , department as td from @tv for xml raw('tr'),elements

但我希望它是动态的,因为当它作为参数传递时我不知道列名。

更新(取自 OP 的评论)

此外,我想在结果 html 中获取 table 列名称,例如

<table> <tr> <td>id</td> <td>username</td> <td>department</td> </tr> <tr> <td>1</td> <td>tom</td> <td>finance</td> </tr> <tr> <td>2</td> <td>mark</td> <td>business</td> </tr> </table>

,所以当我将 table 变量(或 xml )传递给函数时,它 return 像这样

您找到了此答案的增强版本 here

旧答案:

because I don't know the column name when it pass as parameters

这使得调用 SELECT * FROM 这样的东西变得不可能...您可能会考虑动态 SQL,但还有一个很好的选择:FLWOR

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 

)
insert into @tv values(1,'tom','finance'),(2,'mark','business');

SELECT
(
    SELECT *
    FROM @tv 
    FOR XML PATH('tr'),TYPE
).query('for $tr in /tr
         return <tr>
           {
             for $td in $tr/*
             return <td>{$td/text()}</td>
           }
                </tr>')
FOR XML PATH('table')

.query() 将 运行 通过您的 XML 并根据需要重新创建它。

结果:

<table>
  <tr>
    <td>1</td>
    <td>tom</td>
    <td>finance</td>
  </tr>
  <tr>
    <td>2</td>
    <td>mark</td>
    <td>business</td>
  </tr>
</table>

##更新 ##This 是一个 FUNCTIONXML 基础上使用 FLWOR

的解决方案

它将任何 SELECT 转换为 XHTML table:调用就像这样简单:

SELECT dbo.CreateHTMLTable((SELECT TOP 5 * FROM sys.objects FOR XML RAW,ELEMENTS XSINIL));

这就是密码

CREATE FUNCTION dbo.CreateHTMLTable(@SelectForXmlRawElementsXsinil XML)
RETURNS XML
AS
BEGIN

RETURN
(
    SELECT  
    @SelectForXmlRawElementsXsinil.query('let $first:=/row[1]
                return 
                <tr> 
                {
                for $th in $first/*
                return <td>{local-name($th)}</td>
                }
                </tr>') AS thead
    ,@SelectForXmlRawElementsXsinil.query('for $tr in /row
                 return 
                 <tr>
                 {
                 for $td in $tr/*
                 return <td>{string($td)}</td>
                 }
                 </tr>') AS tbody
    FOR XML PATH('table'),TYPE
);
END
GO

--模型-table 数据

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 
)
--NULL value in row=2!!!
insert into @tv values(1,'tom','finance'),(2,NULL,'business');

--你就是这么用的

SELECT dbo.CreateHTMLTable((SELECT * FROM @tv FOR XML RAW,ELEMENTS XSINIL));

--清理

DROP FUNCTION dbo.CreateHTMLTable;

returns 注意最后一行的 NULL 值!

<table>
  <thead>
    <tr>
      <td>id</td>
      <td>username</td>
      <td>department</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>tom</td>
      <td>finance</td>
    </tr>
    <tr>
      <td>2</td>
      <td />
      <td>business</td>
    </tr>
  </tbody>
</table>

##UPDATE 可能的增强功能

  • 您可以通过 CSS
  • 轻松控制布局
  • 您可以为 tabletheadtbody 传入 class 名称...以获得更好的 CSS-control
  • 可以传入一个 one-row-footer 并将聚合值作为第二个参数并将其附加为 <tfoot>