我有这个问题:
SELECT [content_id]
,[content_html]
,[date_created]
,folder_id
FROM content ct
where folder_id=126
order by content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')
当我运行此查询时,这是生成的XML文件:
<PressReleases>
<PressRelease>
<content_id>6442452927</content_id>
<content_html><root><Date>2015-12-02</Date>
<Description><p class="customHeader">jobs to Philadelphia.</p>
<p>mtext in here.</p>
<p>mtext in here.</p>
</Description>
<SEO><h1>Pennsylvania Location</h1>
<div class="bulletRightBar"> The move was made possible in part by the Philadelphia Jobs
Credit</div>
</SEO>
</root></content_html>
<date_created>2015-12-02T09:47:12</date_created>
<folder_id>126</folder_id>
</PressRelease>
<PressReleases>
我需要的是这个XML文件:
<PressReleases>
<PressRelease>
<content_id>6442452927</content_id>
<content_html><root><Date>2015-12-02</Date>
<Description><p class="customHeader">jobs to Philadelphia.</p>
<p>mtext in here.</p>
<p>mtext in here.</p>
</Description>
<SEO><h1>Pennsylvania Location</h1>
<div class="bulletRightBar"> The move was made possible in part by the Philadelphia Jobs
Credit</div>
</SEO>
</root></content_html>
<date_created>2015-12-02T09:47:12</date_created>
<folder_id>126</folder_id>
</PressRelease>
<PressReleases>
在<content_html>
内,我想将<root>
<date>
和<Description>
作为XML元素,但将其余部分保留为编码的html。
答案 0 :(得分:2)
它不漂亮,但您可以将XML字段转换为字符串,使用REPLACE函数并将其转换回XML,如下所示。您可能希望创建一个函数来执行此操作,因为该行将进行大量替换:
SELECT [content_id]
,cast(REPLACE(cast([content_html] as varchar(max)),'<root>','<root>') as xml)
,[date_created]
,folder_id
FROM content ct
where folder_id=126
order by content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')
或者这是一种用函数
调用它的方法CREATE FUNCTION [dbo].[XML_Replace]
(@XML_Field XML)
RETURNS XML
BEGIN
DECLARE @xml varchar(max)
DECLARE @xml_Mid varchar(max)
DECLARE @strtBigInt bigint
, @endBigInt bigint
SET @xml = cast(@XML_Field as varchar(max))
SET @strtBigInt = CHARINDEX('<Description>',@xml)
SET @endBigInt = CHARINDEX('</SEO>',@xml)
SET @xml_Mid = SUBSTRING(@xml, @strtBigInt+19,@endBigInt-@strtBigInt-19);
RETURN(cast(REPLACE(REPLACE(REPLACE(REPLACE(substring(@xml,0,@strtBigInt+19),'<','<'),'>','>') + @xml_Mid + REPLACE(REPLACE(substring(@xml,@endBigInt,Len(@xml)),'<','<'),'>','>'),'</Description>','</Description>'),'<SEO>','<SEO>') as xml));
END
然后在代码中使用功能:
SELECT [content_id]
,dbo.XML_Replace([content_html]) as content_html
,[date_created]
,folder_id
FROM content ct
where folder_id=126
order by content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')
答案 1 :(得分:2)
看起来[content_html]
存储为字符串(也许nvarchar
?)。它的内容看起来像一个格式良好的XML。如果是这种情况,可以CAST
将XML正确地合并到结果集中:
-- Test Data Set
WITH content AS (
SELECT
6442452927 AS [content_id],
N'<root><Date>2015-12-02</Date>
<Description><p class="customHeader">jobs to Philadelphia.</p>
<p>mtext in here.</p>
<p>mtext in here.</p>
</Description>
<SEO><h1>Pennsylvania Location</h1>
<div class="bulletRightBar"> The move was made possible in part by the Philadelphia Jobs
Credit</div>
</SEO>
</root>' AS [content_html],
CAST('2015-12-02T09:47:12' AS DATETIME2) AS [date_created],
126 AS [folder_id],
1 AS [content_title]
)
-- Query
SELECT [content_id]
,CAST((Select
CAST([content_html] AS XML).query('/root/Date/node()') AS [Date]
,CAST(CAST([content_html] AS XML).query('/root/Description/node()') AS nvarchar(max)) As [Description]
,CAST(CAST([content_html] AS XML).query('/root/SEO/node()') AS nvarchar(max)) AS [SEO]
FOR XML PATH('root'), ROOT ('content_html')) As XML)
,[date_created]
,[folder_id]
FROM content ct
WHERE folder_id=126
ORDER BY content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')
答案 2 :(得分:2)
关于这一点的棘手问题是您的content_html
字段既不包含XML也不包含HTML。这是一种非常奇怪的数据编码方式。如果可能,您可能希望转换字段中的数据,使其成为XML,这将使此查询变得非常容易。例如,您可以将您提供的数据中的字段转换为:
<root>
<Date>2015-12-02</Date>
<Description><p class="customHeader">jobs to Philadelphia.</p>
<p>mtext in here.</p>
<p>mtext in here.</p>
</Description>
<SEO><h1>Pennsylvania Location</h1>
<div class="bulletRightBar"> The move was made possible in part by the Philadelphia Jobs
Credit</div>
</SEO>
</root>
如果您无法更改数据的存储方式,获得此功能的一种方法是使用下面的代码来回转换。子查询创建一个名为[content_xml]
的字段,该字段将content_html
字段中的数据转换为XML数据类型。这假设您的所有数据都可以转换为有效的XML。然后,对于XML中root
下的每个节点,它会重建节点并使用CDATA封装数据,以便保留所需的格式。
--set up test data
create table #content
([content_id] bigint
,[content_html] varchar(max)
,[date_created] datetime
,folder_id int
, content_title varchar(50)
)
insert into #content
values (
6442452927,
'<root><Date>2015-12-02</Date>
<Description><p class="customHeader">jobs to Philadelphia.</p>
<p>mtext in here.</p>
<p>mtext in here.</p>
</Description>
<SEO><h1>Pennsylvania Location</h1>
<div class="bulletRightBar"> The move was made possible in part by the Philadelphia Jobs
Credit</div>
</SEO>
</root>',
'2015-12-02T09:47:12',
126,
'Content Title')
--Output
select [content_id],
(
SELECT
CONVERT(xml,
'<' + convert(varchar(max),T.c.query('local-name(.)')) + '>'
+ (select convert(xml, '<![CDATA[' + convert(varchar(max),T.c.query('node()')) + ']]>') for xml path(''))
+ '</' + convert(varchar(max),T.c.query('local-name(.)')) + '>'
)
FROM content_xml.nodes('/root/*') T(c)
for xml path(''), type
) as [content_html/root]
,[date_created]
,folder_id
from
(
SELECT *,
convert(xml,convert(xml,content_html).value('.','varchar(max)')) [content_xml]
FROM #content ct
) AllData
order by content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')
答案 3 :(得分:1)
Plz尝试这个
SELECT [content_id]
,CONVERT(XML,REPLACE(REPLACE([content_html],'<','<'),'>','>')) AS [content_html]
,[date_created]
,folder_id
FROM content ct
WHERE folder_id=126
ORDER BY content_title
FOR XML PATH('PressRelease'), ROOT ('PressReleases')