【问题标题】:How do I create ENTITY references in the DOCTYPE using perl/LibXML如何使用 perl/LibXML 在 DOCTYPE 中创建实体引用
【发布时间】:2017-11-06 11:38:29
【问题描述】:

我正在尝试创建以下包含实体声明的 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 documentation 展示了如何向文档添加实体引用,但没有展示如何在 DOCTYPE 中声明实体。

similar (but PHP-based) question 指向将实体引用创建为字符串并对其进行解析。 这也是 Perl 中最好的方法吗?

【问题讨论】:

  • 实体声明是 XML_ENTITY_DECL 类型的节点,作为 DTD 节点的子节点存在。 $node-&gt;addChild 不支持添加XML_ENTITY_DECL 类型的节点,因此即使您可以创建它也无法添加。因此,已经发布的解析生成方法解决方案可能是做你想做的唯一方法。

标签: xml perl entity dtd xml-libxml


【解决方案1】:

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/>

【讨论】:

  • 感谢您的快速回复。我在文档中读过,但认为我可能遗漏了一些东西,例如在XML::LibXML::Dtd.
猜你喜欢
  • 1970-01-01
  • 2019-08-12
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 2012-02-10
相关资源
最近更新 更多