Delphi - TXMLDocument可以配置为忽略不正确的DTD实体吗?

时间:2017-02-17 13:23:36

标签: delphi exception entity dtd txmldocument

我正在用RAD Studio XE7编写Delphi代码。在我的一个项目中,我需要解析几个SVG文件以在屏幕上绘制其内容。为此,我使用TXMLDocument解析器。

我的一个源SVG包含此XML数据:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Calque_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"
 viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<metadata>
    <sfw  xmlns="&ns_sfw;">
        <slices></slices>
        <sliceSourceBounds  height="21.334" width="32" bottomLeftOrigin="true" y="1.833" x="-4.501"></sliceSourceBounds>
    </sfw>
</metadata>
<path fill="#29ABE2" d="M4,8h24v13.333h2.667v-16H1.334v16h2.667L4,8L4,8z M21.333,22.667c-0.256,0.536-1.527,0.967-2.667,1.181V24
h-5.333v-0.152c-1.14-0.215-2.411-0.645-2.667-1.181H-0.001V24c0,1.467,4,2.667,4,2.667h24c0,0,4-1.2,4-2.667v-1.333H21.333
L21.333,22.667z M26.667,25.333h-1.333V24h1.333V25.333z"/>
</svg>

我知道上述XML的内容不完整,格式良好的SVG应该包含此XML数据:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
    <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
    <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
    <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
    <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
    <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
    <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
    <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id="Calque_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px"
 viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<metadata>
    <sfw  xmlns="&ns_sfw;">
        <slices></slices>
        <sliceSourceBounds  height="21.334" width="32" bottomLeftOrigin="true" y="1.833" x="-4.501"></sliceSourceBounds>
    </sfw>
</metadata>
<path fill="#29ABE2" d="M4,8h24v13.333h2.667v-16H1.334v16h2.667L4,8L4,8z M21.333,22.667c-0.256,0.536-1.527,0.967-2.667,1.181V24
h-5.333v-0.152c-1.14-0.215-2.411-0.645-2.667-1.181H-0.001V24c0,1.467,4,2.667,4,2.667h24c0,0,4-1.2,4-2.667v-1.333H21.333
L21.333,22.667z M26.667,25.333h-1.333V24h1.333V25.333z"/>
</svg>

但是,在我的情况下,DTD实体是无关紧要的(我对它们什么都不做),只有svg标签中的部分让我感兴趣。但是,如果我尝试加载这样的XML,TXMLDocument解析器会引发“引用未定义的实体'ns_extend'”异常,并拒绝加载SVG。

所以我的问题是,有没有办法通知TXMLDocument解析器,如果损坏DTD实体应该被忽略,并强制解析器继续静默读取文档?或者,唯一的方法是预处理XML,并检测并删除此类损坏?

(注意:如果可能的话,我想避免预先考虑.SVG可能来自任何地方,其中一些可能包含小或重的损坏,我希望以最通用的方式处理最大值。开始为所有可能的特殊情况添加特殊规则是一种痛苦的方式。如果TXMLDocument解析器能够忽略这种错误,我会更喜欢。)

1 个答案:

答案 0 :(得分:0)

使用TXMLDocument他们无法忽略DOCTYPE,唯一的方法是编辑xml文件,然后用TXMLDocument解析它并手动删除它

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
    <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
    <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
    <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
    <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
    <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
    <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
    <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>

但是,它们是一些其他xml解析器,它们与Txmldocument完全相似(相同的方法名称和属性名称,完全相似,无需重做代码),比TXMLDocument快100倍,并且使用更少的内存(Txmldocument是你可以找到更糟糕的... ..而忽略了DTD :)