2016-08-06 16 views
2

In PHP kann man optionale Argumente an verschiedene XML-Parser übergeben, von denen einer LIBXML_NOENT ist. Die documentation hat dies zu sagen:Was macht LIBXML_NOENT (und warum heißt es nicht LIBXML_ENT)?

LIBXML_NOENT (integer)
Ersatzeinheiten

Substitute entities ist nicht sehr informativ (welche Einheiten wann sie ersetzt?). Aber ich denke, es ist fair anzunehmen, dass NOENT ist kurz für NO_ENTITIES oder , so scheint es eine faire Annahme zu sein, dass dieses Flag das Parsen von (externen) Entitäten deaktiviert.

Aber das ist in der Tat nicht der Fall:

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

Das Ergebnis ist, dass der Inhalt der Datei/etc/passwd Echo wird. Ohne das Argument LIBXML_NOENT ist dies nicht der Fall.

Für nicht externe Entitäten scheint die Markierung keine Wirkung zu haben. Beispiel:

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

Das Ergebnis dieses Codes ist "TEST", mit und ohne LIBXML_NOENT.

Das Flag scheint keine Auswirkungen auf vordefinierte Entitäten wie &lt; zu haben.

Also meine Fragen sind:

  • Was genau macht die LIBXML_NOENT Flagge tun?
  • Warum heißt es LIBXML_NOENT? Was ist es kurz und würde nicht LIBXML_ENT oder LIBXML_PARSE_EXTERNAL_ENTITIES eine bessere Passform sein?
  • Gibt es ein Flag, das das Parsen aller Entitäten verhindert?
+1

Es [abgebildet] (https://github.com/php/php-src/blob/ef0279b640b19f6294a1429f9e04019b1f72d69c/ext/libxml/libxml.c#L801) die libxml konstant 'XML_PARSE_NOENT' wenn das gibt Ihnen nichts zu suchen auf. Es ist sehr vage beschrieben ... – miken32

Antwort

2

F: Was genau macht das LIBXML_NOENT Flag?

Das Flag ermöglicht das Ersetzen von externen XML-Zeichenentitätsreferenzen.

Q: Warum heißt es LIBXML_NOENT? Was ist es kurz und würde nicht LIBXML_ENT oder LIBXML_PARSE_EXTERNAL_ENTITIES besser passen?

Der Name ist in der Tat irreführend. Ich denke, dass NOENT einfach bedeutet, dass der Knotenbaum des geparsten Dokuments keine Entity-Knoten enthalten wird, so dass der Parser Entitäten ersetzen wird. Ohne NOENT erstellt der Parser DOMEntityReference Knoten für Entitätsreferenzen.

F: Gibt es ein Flag, das das Parsen aller Entitäten verhindert?

LIBXML_NOENT ermöglicht die Ersetzung von alle Entity-Referenzen.Wenn Sie nicht möchten, dass Entitäten erweitert werden, lassen Sie das Flag einfach weg. Zum Beispiel

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

druckt

<?xml version="1.0"?> 
<!DOCTYPE test [ 
<!ENTITY c "TEST"> 
]> 
<test>&c;</test> 

Es scheint, dass textContent Einheiten auf seinem eigenen ersetzt, die eine Besonderheit der PHP-Bindungen sein könnten. Ohne LIBXML_NOENT führt dies zu einem unterschiedlichen Verhalten für interne und externe Entitäten, da letztere nicht geladen werden.

+0

Danke für Ihre Antwort! In Ihrer Antwort auf die dritte Frage meinen Sie "ermöglicht" statt "deaktiviert", oder? Und gibt es eine Möglichkeit, auf das DOM zuzugreifen, ohne dass Entitäten geparst werden? Da es nicht nur 'textContent' ist, ist es auch' $ dom-> getElementsByTagName ('test') -> item (0) -> nodeValue'. Wenn ich 'print_r ($ dom-> childNodes-> item (1));' es scheint auch immer geparst wird, gibt es keine 'DOMentityReference' für interne Entitäten. Aber für externe Entitäten macht 'LIBXML_NOENT' hier einen Unterschied. Die Ausgabe von "saveXML" ist jedoch in der Tat unterschiedlich, sogar für interne Entitäten. – tim

+0

@tim Ich habe die Antwort auf die dritte Frage korrigiert. 'nodeValue' und' textContent' sind normalerweise identisch. Um auf den 'DOMentityReference'-Knoten zuzugreifen, versuchen Sie' $ dom-> documentElement-> childNodes-> item (0) 'oder' $ dom-> documentElement-> firstChild'. – nwellnhof