我正在尝试读取为IAM数据库提供的xml文件,以便构建数据库。我正在使用Matlab读取这些文件并使用xmlread
。
xml文件远远超过1500,几乎所有文件都给出了同样的错误:
Java exception occurred:
java.io.FileNotFoundException: http://www.fki.inf.unibe.ch/iamdb/form-metadata.dtd
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLEntityManager.startEntity(Unknown Source)
以下是我尝试阅读的xml文件之一:http://pastebin.com/TtQz4ZCV
顶部未找到的链接是404页面,因此它不再存在而且忘记修复它。
现在我唯一的选择是从所有xml文件中手动删除此行吗?还是有一个简单的解决方法来阅读这个?
答案 0 :(得分:2)
您需要为解析器禁用外部DTD加载。要完成此操作,您可以创建自定义DocumentBuilder
对象disable the external DTD loading,并将其作为xmlread
的第二个输入传递。
隐藏的xmlread
文档(如果您使用edit xmlread
打开文件,则可见):
% Advanced use:
% Note that FILENAME can also be an InputSource, File, or InputStream object
% DOMNODE = XMLREAD(FILENAME,...,P,...) where P is a DocumentBuilder object
% DOMNODE = XMLREAD(FILENAME,...,'-validating',...) will create a validating
% parser if one was not provided.
% DOMNODE = XMLREAD(FILENAME,...,ER,...) where ER is an EntityResolver will
% will set the EntityResolver before parsing
% DOMNODE = XMLREAD(FILENAME,...,EH,...) where EH is an ErrorHandler will
% will set the ErrorHandler before parsing
% [DOMNODE,P] = XMLREAD(FILENAME,...) will return a parser suitable for passing
% back to XMLREAD for future parses.
%
所以这最终看起来像这样:
% Create the DocumentBuilder
builder = javax.xml.parsers.DocumentBuilderFactory.newInstance;
% Disable validation
builder.setFeature('http://apache.org/xml/features/nonvalidating/load-external-dtd', false);
% Read your file
xml = xmlread(filename, builder);
请注意,此可能可能导致您的文件被错误地解析。
<强>更新强>
所以仔细研究一下,一旦我们通过DTD验证失败,FEX xml2struct
就无法正确处理XML中的DOCTYPE
条目,并试图像处理它一样处理它正常节点。您可以修改xml2struct
的来源以在内部检测此内容:
if node.getNodeType == node.DOCUMENT_TYPE_NODE
但是,删除所有XML文件的所有DOCTYPE
可能会更容易。以下脚本应该能够执行此操作。
folder = 'directory/where/all/files/live';
files = dir(fullfile(folder, '*.xml'));
for k = 1:numel(files)
filename = fullfile(folder, files(k).name);
fid = fopen(filename, 'rt');
content = fread(fid, '*char')';
fclose(fid);
newcontent = regexprep(content, '\n\s*?<!DOCTYPE.*?(?=\n)', '');
fout = fopen(filename, 'wt');
fwrite(fout, newcontent);
fclose(fout);
end