在 SQL 中声明 XML 变量时出现非法 XML 个字符
Illegal XML Characters When Declaring XML Variable In SQL
问题
我试图在我的 SQL 查询中声明一个 XML 变量并将其设置为等于 this XML 文件,如下所示:DECLARE @x XML = 'xml content here';
.
但是,当我尝试使用当前的 XML 文件执行此操作时,我的屏幕上显示了以下错误消息:
Msg 9420, Level 16, State 1, Line 1
XML parsing: line 1132, character 265, illegal xml character
我已经尝试解决的方法
- 我试图通过用两个单引号替换 XML 文件中的所有单引号然后复制到查询中来转义单引号。没有运气。
- 我试过去掉 & 符号,但这似乎不起作用。在 SQL 检测到错误的附近,似乎没有任何特殊字符。又没运气了。
问题
在我看来,单引号不是问题所在。我无法准确找到非法字符是什么,以及如何过滤掉这些字符。也许从外部文件导入 XML 文件并将内容设置为变量而不是听到编码将解决问题。这将如何工作?我也知道单引号必须用两个单引号代替。我做到了,但我仍然有完全相同的问题。感谢任何帮助理解这个问题。
系统参数
- MS SQL 服务器管理工作室
- Windows 服务器 2012 R2 标准版
完整代码
这是我正在执行的给出错误的完整代码:
DECLARE @x XML = ' copy xml file here... ';
With MyPersonCTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PersonID
,p.value('FirstName[1]','varchar(max)') AS FirstName
,p.value('LastName[1]','varchar(max)') AS LastName
,p.value('Biography[1]','varchar(max)') AS Biography
,p.value('Expertise[1]','varchar(max)') AS Expertise
,p.value('Image[1]','varchar(max)') AS Image
,p.value('Link[1]','varchar(max)') AS Link
,p.query('Books') AS BookNode
,p.query('Articles') AS ArticleNode
--same for Papers, Artwork...
FROM @x.nodes('/People/Person') AS A(p)
)
,MyBooksCTE AS
(
SELECT MyPersonCTE.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS BookID
,x.value('Year[1]','int') AS BookYear
,x.value('Details[1]','varchar(max)') AS BookDetails
FROM MyPersonCTE
CROSS APPLY MyPersonCTE.BookNode.nodes('/Books/Book') A(x)
)
,MyArticlesCTE AS
(
SELECT MyPersonCTE.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ArticleID
,x.value('Year[1]','int') AS ArticleYear
,x.value('Details[1]','varchar(max)') AS ArticleDetails
FROM MyPersonCTE
CROSS APPLY MyPersonCTE.ArticleNode.nodes('/Articles/Article') A(x)
)
--same for Papers, Artwork...
SELECT p.*
,b.BookID
,b.BookYear
,b.BookDetails
,a.ArticleID
,a.ArticleYear
,a.ArticleDetails
INTO #tempAllData
FROM MyPersonCTE AS p
LEFT JOIN MyBooksCTE AS b ON p.PersonID=b.PersonID
LEFT JOIN MyArticlesCTE AS a ON p.PersonID=a.PersonID ;
--#tempAllData is now filled with all data, copied in all combination: much to much
--but DISTINCT is your friend
--in this case you'd use the PersonID as FK in all related tables
SELECT DISTINCT PersonID,FirstName,LastName,Biography,Expertise --other fields
FROM #tempAllData;
SELECT DISTINCT PersonID,BookID,BookYear,BookDetails
FROM #tempAllData;
SELECT DISTINCT PersonID,ArticleID,ArticleYear,ArticleDetails
FROM #tempAllData;
DROP TABLE #tempAllData;
看,这是重现错误的简化示例
在这个片段中,你有两倍的名字 "O’Brien" 其中 ’ 制造麻烦
而这里“体验身体温暖促进人际温暖”的开篇和闭幕都是有问题的
DECLARE @x XML=
'<?xml version="1.0" encoding="UTF-8"?>
<People>
<Person>
<FirstName>Katherine</FirstName>
<LastName>Corker</LastName>
<Articles>
<Article>
<Year></Year>
<Details><![CDATA[<p>Corker, K. S., Lynott, D., Wortman, J., Connell, L., Donnellan, M. B., Lucas, R. E., & O’Brien, K. (2014). High quality direct replications matter: Response to Williams (2014). Social Psychology, 45, 324-326. Available <a href="https://www.academia.edu/attachments/35015451/download_file?st=MTQxMzMwNDE0MiwxMzguMjguOS4xNjEsMjEzMTg%3D&s=work_strip">here.</a></p>
<p>Lynott, D., Corker, K. S., Wortman, J., Connell, L., Donnellan, M. B., Lucas, R. E., & O’Brien, K. (2014). Replication of “Experiencing physical warmth promotes interpersonal warmth” by Williams & Bargh (2008, Science). Social Psychology, 45, 216-222. Available <a href="https://www.academia.edu/attachments/33247494/download_file?st=MTQxMzMwNDE0MiwxMzguMjguOS4xNjEsMjEzMTg%3D&s=work_strip">here.</a></p>]]></Details>
</Article>
</Articles>
</Person>
</People>';
SELECT @x;
现在只需更改此
'<?xml version="1.0" encoding="UTF-8"?>
到这个(不要忘记开头的"N"强制这个到Unicode)
N'<?xml version="1.0" encoding="UTF-16"?>
但试试这个:
DECLARE @yourXML AS XML=
(
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'X:\Path2file\faculty-xml.xml', SINGLE_BLOB) AS x
);
SELECT @yourXML;
有了这个,您就不必为环境而烦恼,您只需从磁盘上的某个位置读取文件...
问题
我试图在我的 SQL 查询中声明一个 XML 变量并将其设置为等于 this XML 文件,如下所示:DECLARE @x XML = 'xml content here';
.
但是,当我尝试使用当前的 XML 文件执行此操作时,我的屏幕上显示了以下错误消息:
Msg 9420, Level 16, State 1, Line 1
XML parsing: line 1132, character 265, illegal xml character
我已经尝试解决的方法
- 我试图通过用两个单引号替换 XML 文件中的所有单引号然后复制到查询中来转义单引号。没有运气。
- 我试过去掉 & 符号,但这似乎不起作用。在 SQL 检测到错误的附近,似乎没有任何特殊字符。又没运气了。
问题
在我看来,单引号不是问题所在。我无法准确找到非法字符是什么,以及如何过滤掉这些字符。也许从外部文件导入 XML 文件并将内容设置为变量而不是听到编码将解决问题。这将如何工作?我也知道单引号必须用两个单引号代替。我做到了,但我仍然有完全相同的问题。感谢任何帮助理解这个问题。
系统参数
- MS SQL 服务器管理工作室
- Windows 服务器 2012 R2 标准版
完整代码
这是我正在执行的给出错误的完整代码:
DECLARE @x XML = ' copy xml file here... ';
With MyPersonCTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PersonID
,p.value('FirstName[1]','varchar(max)') AS FirstName
,p.value('LastName[1]','varchar(max)') AS LastName
,p.value('Biography[1]','varchar(max)') AS Biography
,p.value('Expertise[1]','varchar(max)') AS Expertise
,p.value('Image[1]','varchar(max)') AS Image
,p.value('Link[1]','varchar(max)') AS Link
,p.query('Books') AS BookNode
,p.query('Articles') AS ArticleNode
--same for Papers, Artwork...
FROM @x.nodes('/People/Person') AS A(p)
)
,MyBooksCTE AS
(
SELECT MyPersonCTE.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS BookID
,x.value('Year[1]','int') AS BookYear
,x.value('Details[1]','varchar(max)') AS BookDetails
FROM MyPersonCTE
CROSS APPLY MyPersonCTE.BookNode.nodes('/Books/Book') A(x)
)
,MyArticlesCTE AS
(
SELECT MyPersonCTE.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ArticleID
,x.value('Year[1]','int') AS ArticleYear
,x.value('Details[1]','varchar(max)') AS ArticleDetails
FROM MyPersonCTE
CROSS APPLY MyPersonCTE.ArticleNode.nodes('/Articles/Article') A(x)
)
--same for Papers, Artwork...
SELECT p.*
,b.BookID
,b.BookYear
,b.BookDetails
,a.ArticleID
,a.ArticleYear
,a.ArticleDetails
INTO #tempAllData
FROM MyPersonCTE AS p
LEFT JOIN MyBooksCTE AS b ON p.PersonID=b.PersonID
LEFT JOIN MyArticlesCTE AS a ON p.PersonID=a.PersonID ;
--#tempAllData is now filled with all data, copied in all combination: much to much
--but DISTINCT is your friend
--in this case you'd use the PersonID as FK in all related tables
SELECT DISTINCT PersonID,FirstName,LastName,Biography,Expertise --other fields
FROM #tempAllData;
SELECT DISTINCT PersonID,BookID,BookYear,BookDetails
FROM #tempAllData;
SELECT DISTINCT PersonID,ArticleID,ArticleYear,ArticleDetails
FROM #tempAllData;
DROP TABLE #tempAllData;
看,这是重现错误的简化示例
在这个片段中,你有两倍的名字 "O’Brien" 其中 ’ 制造麻烦 而这里“体验身体温暖促进人际温暖”的开篇和闭幕都是有问题的
DECLARE @x XML=
'<?xml version="1.0" encoding="UTF-8"?>
<People>
<Person>
<FirstName>Katherine</FirstName>
<LastName>Corker</LastName>
<Articles>
<Article>
<Year></Year>
<Details><![CDATA[<p>Corker, K. S., Lynott, D., Wortman, J., Connell, L., Donnellan, M. B., Lucas, R. E., & O’Brien, K. (2014). High quality direct replications matter: Response to Williams (2014). Social Psychology, 45, 324-326. Available <a href="https://www.academia.edu/attachments/35015451/download_file?st=MTQxMzMwNDE0MiwxMzguMjguOS4xNjEsMjEzMTg%3D&s=work_strip">here.</a></p>
<p>Lynott, D., Corker, K. S., Wortman, J., Connell, L., Donnellan, M. B., Lucas, R. E., & O’Brien, K. (2014). Replication of “Experiencing physical warmth promotes interpersonal warmth” by Williams & Bargh (2008, Science). Social Psychology, 45, 216-222. Available <a href="https://www.academia.edu/attachments/33247494/download_file?st=MTQxMzMwNDE0MiwxMzguMjguOS4xNjEsMjEzMTg%3D&s=work_strip">here.</a></p>]]></Details>
</Article>
</Articles>
</Person>
</People>';
SELECT @x;
现在只需更改此
'<?xml version="1.0" encoding="UTF-8"?>
到这个(不要忘记开头的"N"强制这个到Unicode)
N'<?xml version="1.0" encoding="UTF-16"?>
但试试这个:
DECLARE @yourXML AS XML=
(
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'X:\Path2file\faculty-xml.xml', SINGLE_BLOB) AS x
);
SELECT @yourXML;
有了这个,您就不必为环境而烦恼,您只需从磁盘上的某个位置读取文件...