鉴于以下两个文件:
doc.xml
<!DOCTYPE TEST [
<!ENTITY % get_em SYSTEM "entities.ent" >
%get_em;
]>
<TEST>
<COMPANY_ID>&COMPANY_ID;</COMPANY_ID>
</TEST>
entities.ent
<!ENTITY COMPANY_ID "84500">
<!ENTITY SPN_FIRM_ID "5900">
<!ENTITY SPN_CUSTD_REL_ID "40001">
<!ENTITY CUSTD_FIRM_NBR "229">
<!ENTITY CUSTD_FIRM_ID "5901">
<!ENTITY MASTERACCOUNT "TAL">
我可以成功使用xmllint
:
xmllint --loaddtd --noent --dropdtd doc.xml
<?xml version="1.0"?>
<TEST>
<COMPANY_ID>84500</COMPANY_ID>
</TEST>
我怎么能在Perl和XML :: Simple中使用这个想法?
$ perl -MData::Dumper -MXML::Simple -e 'print Dumper XMLin q{doc.xml}'
doc.xml:4: parser error : PEReference: %get_em; not found
%get_em;
^
doc.xml:9: parser error : Entity 'COMPANY_ID' not defined
<COMPANY_ID>&COMPANY_ID;</COMPANY_ID>
^
经过一些评论后,我已尝试使用XML::LibXML::Simple
它确实看起来好一点,但实体仍未得到解决
$ perl -MData::Dumper -MXML::LibXML::Simple -e 'print Dumper XMLin q{doc.xml}'
./doc.xml:9: parser error : Entity 'COMPANY_ID' not defined
<COMPANY_ID>&COMPANY_ID;</COMPANY_ID>
^
嗯,上面的PEReference
突出......什么是PE
?
但更重要的是,如何通过XML :: Simple读取外部DTD的Perl?
我累了XML::Simple::DTDReader
但我觉得这个模块非常严格,特别是它指出specifically 没有XML::Simple
支持无数的选项 !
如果我在doc.xml
本身中包含ENTITY声明,它就可以工作..所以显然XML::Simple
知道如何处理DOCTYPE
只有我想要使用SYSTEM
的外部DTD,以及我坚持让它工作的地方。
答案 0 :(得分:1)
XML :: LibXML默认会扩展实体,因此您可以使用
$ perl -e'
use Data::Dumper qw( Dumper );
use XML::LibXML qw( );
use XML::Simple qw( XMLin );
my $xml = XML::LibXML->new()->parse_file("doc.xml")->toString();
my $doc = XMLin($xml);
print(Dumper($doc));
'
$VAR1 = {
'COMPANY_ID' => '84500'
};
这也可以通过覆盖XML :: Simple-compatibility设置来实现XML :: LibXML :: Simple。
$ perl -e'
use Data::Dumper qw( Dumper );
use XML::LibXML::Simple qw( XMLin );
my $doc = XMLin("doc.xml",
ParserOpts => {
load_ext_dtd => 1,
ext_ent_handler => undef,
},
);
print(Dumper($doc));
'
$VAR1 = {
'COMPANY_ID' => '84500'
};
答案 1 :(得分:0)