在PHP中,可以将可选参数传递给各种XML解析器,其中一个是LIBXML_NOENT
。 documentation可以这样说:
LIBXML_NOENT(整数)
替代实体
Substitute entities
信息量不大(什么实体?什么时候替换?)。但我认为假设NOENT
是NO_ENTITIES
或NO_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;
结果是回显了/ etc / passwd的内容。没有LIBXML_NOENT
参数,情况并非如此。
对于非外部实体,该标志似乎没有任何效果。示例:
$xml = '<!DOCTYPE root [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->textContent;
此代码的结果为“TEST”,包含和不包含LIBXML_NOENT
。
该标志似乎对预定义的实体(例如<
。
所以我的问题是:
LIBXML_NOENT
标志到底有什么作用?LIBXML_NOENT
?什么是简短的,而不是LIBXML_ENT
或LIBXML_PARSE_EXTERNAL_ENTITIES
更合适?答案 0 :(得分:3)
问: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();
打印
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY c "TEST">
]>
<test>&c;</test>
似乎textContent
本身替换了实体,这可能是PHP绑定的特性。没有LIBXML_NOENT
,它会导致内部和外部实体的不同行为,因为后者无法加载。