LIBXML_NOENT是做什么的(为什么不叫LIBXML_ENT)?

tim*_*tim 7 php xml libxml2 xml-parsing

在PHP中,可以将可选参数传递给各种XML解析器,其中之一是LIBXML_NOENT。该文档对此有以下说法:

LIBXML_NOENT(整数)
替代实体

Substitute entities信息不是很丰富(什么实体?何时替换?)。但是我认为可以假设或的NOENT缩写是公平的,因此在我看来,可以合理地假设此标志会禁用(外部)实体的解析。NO_ENTITIESNO_EXTERNAL_ENTITIES

但是事实并非如此:

$xml = '<!DOCTYPE root [<!ENTITY c PUBLIC "bar" "/etc/passwd">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT);
echo $dom->textContent;
Run Code Online (Sandbox Code Playgroud)

结果是回显了/ etc / passwd的内容。没有LIBXML_NOENT论点,事实并非如此。

对于非外部实体,该标志似乎没有任何作用。例:

$xml = '<!DOCTYPE root [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->textContent;
Run Code Online (Sandbox Code Playgroud)

该代码的结果为“ TEST”,带有和不带有LIBXML_NOENT

该标志似乎对诸如的预定义实体没有任何影响&lt;

所以我的问题是:

  • LIBXML_NOENT旗帜到底是做什么的?
  • 为什么叫它LIBXML_NOENT?它的缺点是什么?不适合LIBXML_ENTLIBXML_PARSE_EXTERNAL_ENTITIES更适合?
  • 是否有一个标志实际上阻止了所有实体的解析?

nwe*_*hof 5

问:LIBXML_NOENT标志的作用是什么?

该标志启用XML字符实体引用的替代,无论是否外部。

问:为什么叫LIBXML_NOENT?这是什么缩写,LIBXML_ENT或LIBXML_PARSE_EXTERNAL_ENTITIES会更适合吗?

这个名字确实令人误解。我认为这NOENT只是意味着已解析文档的节点树将不包含任何实体节点,因此解析器将替换实体。如果不使用NOENT,解析器将为实体引用创建DOMEntityReference节点。

问:是否有一个标志实际上阻止了所有实体的解析?

LIBXML_NOENT启用所有实体引用的替换。如果您不希望扩展实体,只需省略该标志。例如

$xml = '<!DOCTYPE test [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->saveXML();
Run Code Online (Sandbox Code Playgroud)

版画

$xml = '<!DOCTYPE test [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->saveXML();
Run Code Online (Sandbox Code Playgroud)

似乎可以textContent自行替换实体,这可能是PHP绑定的特性。没有LIBXML_NOENT,它将导致内部和外部实体的行为不同,因为不会加载内部和外部实体。