如何在 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 是一个 FUNCTION
在 XML
基础上使用 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
轻松控制布局
- 您可以为
table
、thead
、tbody
传入 class 名称...以获得更好的 CSS-control
- 可以传入一个 one-row-footer 并将聚合值作为第二个参数并将其附加为
<tfoot>
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 是一个 FUNCTION
在 XML
基础上使用 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
轻松控制布局
- 您可以为
table
、thead
、tbody
传入 class 名称...以获得更好的 CSS-control - 可以传入一个 one-row-footer 并将聚合值作为第二个参数并将其附加为
<tfoot>