0

我正在用 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 解析器能够忽略这种错误,我将非常喜欢。)

4

1 回答 1

1

使用 TXMLDocument,他们无法忽略 DOCTYPE,唯一的方法是在使用 TXMLDocument 解析之前编辑 xml 文件并手动从中删除

<!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/">
]>

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

于 2017-02-18T08:16:19.953 回答