XML解析分号预期 - 仅在替换&与&

时间:2016-12-12 14:56:29

标签: sql-server xml-parsing

我有以下查询,它有效:

DECLARE @Combined VARCHAR(MAX)

SET @Combined = 'mac cheese';

DECLARE @KeyTable TABLE (Keyword VARCHAR(MAX))
INSERT INTO @KeyTable
SELECT @Combined

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Keyword
    INTO #Temp
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE(Keyword,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM @KeyTable
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n);

SELECT * FROM #Temp

当我尝试在@Combined添加&符时,会出现特殊字符错误:

DECLARE @Combined VARCHAR(MAX)

SET @Combined = 'mac & cheese';

DECLARE @KeyTable TABLE (Keyword VARCHAR(MAX))
INSERT INTO @KeyTable
SELECT @Combined

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Keyword
    INTO #Temp
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE(Keyword,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM @KeyTable
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n);

SELECT * FROM #Temp

所以我添加了一些代码用&amp替换&符号,我得到一个分号错误:

DECLARE @Combined VARCHAR(MAX)

SET @Combined = 'mac & cheese'

SET @Combined = REPLACE(@Combined, '&', '&amp')

DECLARE @KeyTable TABLE (Keyword VARCHAR(MAX))

INSERT INTO @KeyTable
SELECT @Combined;

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
    DROP TABLE #Temp

SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Keyword
    INTO #Temp
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE(Keyword,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM @KeyTable
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n);

SELECT * FROM #Temp

我尝试将分号移到各个位置,甚至添加更多,但它只是不起作用。任何人都可以提供的帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

不,你不应该开始自己替换特殊字符!

下次您的字符串包含<->时会再次中断。

FOR XML PATH()为你付出艰苦的努力:

SELECT 'This is pure text: ' + 'mac & cheese,<test1>,"test2"';
SELECT 'This is encoded: ' + (SELECT 'mac & cheese,<test1>,"test2"' AS [*] FOR XML PATH(''))

第二个结果:This is encoded: mac &amp; cheese,&lt;test1&gt;,"test2"

代码的更新:

您唯一需要改变的是使用(SELECT ... FOR XML PATH())代替裸体 Keyword

DECLARE @KeyTable TABLE (Keyword VARCHAR(MAX))
INSERT INTO @KeyTable VALUES('mac & cheese,<test1>,"test2"');

SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Keyword
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE((SELECT Keyword AS [*] FOR XML PATH('')),',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM @KeyTable
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n);

这将隐式替换所有禁用的字符......

结果

mac & cheese
<test1>
"test2"