2016-08-06 2 views
2

В PHP можно передать необязательные аргументы различным синтаксическим анализаторам XML, одним из которых является LIBXML_NOENT. documentation это сказать об этом:Что делает LIBXML_NOENT (и почему он не называется LIBXML_ENT)?

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; 

Результатом является то, что содержание/и т.д./пароль вторит. Без аргумента LIBXML_NOENT это не так.

Для не внешних объектов флаг, похоже, не имеет никакого эффекта. Пример:

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

Результатом этого кода "TEST", с и без LIBXML_NOENT.

Флаг, похоже, не влияет на предопределенные объекты, такие как &lt;.

Так что мои вопросы:

  • Что именно делает LIBXML_NOENT флаг делать?
  • Почему это называется LIBXML_NOENT? Для чего это не так, и не будет LIBXML_ENT или LIBXML_PARSE_EXTERNAL_ENTITIES лучше подойдет?
  • Есть ли флаг, который фактически предотвращает разбор всех объектов?
+1

Это [сопоставляется с] (https://github.com/php/php-src/blob/ef0279b640b19f6294a1429f9e04019b1f72d69c/ext/libxml/libxml.c#L801) LibXML константа 'XML_PARSE_NOENT' если что дает вам что-нибудь сделать поиск на. Это очень смутно описано ... – miken32

ответ

2

В: Что именно делает флаг 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 это приводит к разному поведению для внутренних и внешних объектов, потому что последнее не будет загружено.

+0

Спасибо за ваш ответ! В ответе на третий вопрос вы подразумеваете 'enable' вместо' disables', правильно? И есть ли способ доступа к DOM без анализируемых объектов? Потому что это не просто 'textContent', это также' $ dom-> getElementsByTagName ('test') -> item (0) -> nodeValue'. Если я делаю 'print_r ($ dom-> childNodes-> item (1));' также кажется, что он всегда разбирается, для внутренних объектов не существует 'DOMEntityReference'. Но для внешних объектов здесь имеет значение 'LIBXML_NOENT'. Выход 'saveXML' действительно отличается, хотя и для внутренних объектов. – tim

+0

@tim Я исправил ответ на третий вопрос. 'nodeValue' и' textContent', как правило, одинаковы. Чтобы получить доступ к узлу 'DOMEntityReference', попробуйте' $ dom-> documentElement-> childNodes-> item (0) 'или' $ dom-> documentElement-> firstChild'. – nwellnhof

Смежные вопросы