修复XML解析的技术:非法限定名称字符

got*_*tqn 4 xml sql t-sql sql-server-2012

是否有解决以下错误的最终解决方案:

消息 9455,级别 16,状态 1,第 8 行
XML 解析:第 1 行,字符 12,非法限定名称字符

将“非法”NVARCHAR字符串转换为XML.

例如:

DECLARE @Text NVARCHAR(MAX)
SET @Text =  '<tag>' + 'Test <'  + '</tag>' 
SELECT CAST(@Text AS XML)
Run Code Online (Sandbox Code Playgroud)

可以使用修复CDATA,但它只处理很少的符号。在类似下面查询的情况下:

DECLARE @Text NVARCHAR(MAX)
SET @Text = '<tag><![CDATA[' + 'Test' + CHAR(28)  + ']]></tag>' -- CHAR(28) --CHAR(8) -- CHAR(29) -- CHAR(63) 
SELECT CAST(@Text AS XML)
Run Code Online (Sandbox Code Playgroud)

它什么也不做。此外,它不能用在 XML 属性值中。

我试图找到一个包含所有破坏 XML 的符号的列表,但我没能做到。因此,每次某些符号破坏 XML 时,我都会找到它并替换它,但这是非常临时且难以维护的解决方案。

对于这种情况是否有完整的解决方案 - 无论是在应用程序中完成还是使用 CLR 函数完成?

Jay*_*vee 6

这取决于 XML 版本,但为了安全起见,您可以做的一件事是替换循环中的所有 C0 控制 ASCII 字符:

DECLARE @counter INT=0
DECLARE @Text NVARCHAR(MAX)
SET @Text = '<tag><![CDATA[' + 'Test' + CHAR(28) + CHAR(55) + CHAR(29) + '<' + ']]></tag>' -- CHAR(28) --CHAR(8) -- CHAR(29) -- CHAR(63) 
WHILE @counter<32
BEGIN
SET @text= REPLACE(@text,CHAR(@counter),'?')
SET @counter=@counter+1
END
SELECT CAST(@Text AS XML)
Run Code Online (Sandbox Code Playgroud)

有关 XML 字符集的更多信息:

http://www.w3.org/TR/xml11/#charsets

http://en.wikipedia.org/wiki/Valid_characters_in_XML

http://en.wikipedia.org/wiki/C0_and_C1_control_codes

  • 上面的第二个链接显示了 XML 1.0 和 XML 1.1 的有效 unicode 值列表 (2认同)