为什么无法在 T-SQL 中启用 DTD 支持?

Why I can't enable DTDs support in T-SQL?

提问人:André 提问时间:10/31/2023 最后编辑:GSergAndré 更新时间:10/31/2023 访问量:61

问:

我正在 T-SQL 中使用 DTD 并用于以下代码:

use customers;

DECLARE @xmlData XML;
SET @xmlData = '<!DOCTYPE replace [<!ENTITY example "Doe"> ]><customer><name>John Doe</name><address>123 Main St, Anytown, USA</address><salary>&example</salary></customer>';

INSERT INTO customers (name, address, salary)
SELECT
    T.c.value('(name/text())[1]', 'NVARCHAR(MAX)'),
    T.c.value('(address/text())[1]', 'NVARCHAR(MAX)'),
    T.c.value('(salary/text())[1]', 'DECIMAL(18, 2)')
FROM @xmlData.nodes('/customers/customer') AS T(c);

我收到以下错误消息。

不允许使用内部子集 DTD 解析 XML。与样式选项 2 一起使用以启用有限的内部子集 DTD 支持。CONVERT

我试图修复转换函数:

SET @xmlData = CONVERT(XML, @xmlData, 2);

Select CONVERT(XML, @xmlData, 2);

似乎没有什么能解决这个问题。有人可以给我一些提示吗?

sql-server xml t-sql dtd

评论

1赞 Panagiotis Kanavos 10/31/2023
DTD 在 2000 年代初期被 XML 模式取代,作为 SOAP 和 Web 服务标准化的一部分。如果要在 SQL Server 中验证 XML 数据,则必须使用 XML 架构

答:

1赞 Thom A 10/31/2023 #1

在分配变量失败后尝试该变量将不起作用。您需要显式显示您拥有的文字字符串:CONVERTCONVERT

DECLARE @xmlData XML;
SET @xmlData = CONVERT(xml,'<!DOCTYPE replace [<!ENTITY example "Doe"> ]><customer><name>John Doe</name><address>123 Main St, Anytown, USA</address><salary>&example</salary></customer>',2);

但是,这会给你一个不同的错误(和打印语句):

消息 9411,级别 16,状态 1,第 2 行
XML 分析:第 1 行,字符 137,应使用分号

XML DTD 已从一个或多个 XML 片段中剥离。外部子集(如果有)已被忽略。

此错误是由于 ;& 符号需要转义为 .如果你在源头修复它,那么它就会起作用,DTD就会被剥离:<salary>&example</salary>&amp;

DECLARE @xmlData XML;
SET @xmlData = CONVERT(xml,'<!DOCTYPE replace [<!ENTITY example "Doe"> ]><customer><name>John Doe</name><address>123 Main St, Anytown, USA</address><salary>&amp;example</salary></customer>',2);
-1赞 André 10/31/2023 #2

因此,我的代码示例的问题是

DECLARE @xmlData XML;

它应该是一个 .NVARCHAR(MAX)