如何使用Perl/libxml在Doctype中创建实体参考



我正在尝试创建以下包含实体声明的DTD:

<!DOCTYPE LinkSet PUBLIC "-//NLM//DTD LinkOut 1.0//EN" "https://www.ncbi.nlm.nih.gov/projects/linkout/doc/LinkOut.dtd" 
[ <!ENTITY icon.url "https://example.com/icon.png"> 
<!ENTITY base.url "https://example.com/content/" > ]>

我可以成功创建Doctype 而无需实体参考:

#!/usr/bin/perl -w
use strict;
use XML::LibXML;
my $doc = XML::LibXML::Document->new('1.0','UTF-8');
my $dtd = $doc->createInternalSubset( "LinkSet", "-//NLM//DTD LinkOut 1.0//EN", "https://www.ncbi.nlm.nih.gov/projects/linkout/doc/LinkOut.dtd" );
my $ls = $doc->createElement( "LinkSet" );
$doc->setDocumentElement($ls);
print $doc->toString;
exit;

导致:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE LinkSet PUBLIC "-//NLM//DTD LinkOut 1.0//EN" "https://www.ncbi.nlm.nih.gov/projects/linkout/doc/LinkOut.dtd">
<LinkSet/>

xml :: libxml文档显示了如何添加对文档的实体参考,但没有如何在Doctype中声明实体。

类似(但基于PHP的(问题指出,将实体引用作为字符串和解析。这也是Perl中最好的方法吗?

XML::LibXML::Document的文档说这个

[文档类]从DOM中指定的XML::LibXML::Node继承了所有函数 规格。这使除根元素以外的节点可以访问 在文档级别 - 例如" DTD"。对这些节点的支持是 目前有限。

也稍后清楚地表明,这些限制的来源是libxml2本身,而不是Perl模块。这是有道理的,因为DTD与XML具有完全不同的语法(甚至XML处理指令(,即使它看起来在表面上相似。

似乎唯一的方法是用所需的DTD解析基本文档并与该文档一起使用

喜欢

use strict;
use warnings 'all';
use XML::LibXML;
my $doc = XML::LibXML->load_xml(string => <<__END_XML__);
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE LinkSet PUBLIC "-//NLM//DTD LinkOut 1.0//EN" "https://www.ncbi.nlm.nih.gov/projects/linkout/doc/LinkOut.dtd" 
[
  <!ENTITY icon.url "https://example.com/icon.png"> 
  <!ENTITY base.url "https://example.com/content/">
]>
<LinkSet/>
__END_XML__
print $doc;

输出

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE LinkSet PUBLIC "-//NLM//DTD LinkOut 1.0//EN" "https://www.ncbi.nlm.nih.gov/projects/linkout/doc/LinkOut.dtd" [
<!ENTITY icon.url "https://example.com/icon.png">
<!ENTITY base.url "https://example.com/content/">
]>
<LinkSet/>

最新更新