2015-02-05 3 views
0

번거로운 문자가 포함될 수있는 문자열 (예 : &, <)을 추가하면 DOMDocument는 문자열을 살균하는 대신 경고를 발생시킵니다.PHP DOMDocument : 요소에 텍스트를 안전하게 추가하는 가장 좋은 방법은 무엇입니까

문자열을 xml- 안전하게 만드는 간결한 방법을 찾고 있습니다. 이상적으로는 DOMDocument 라이브러리를 활용하는 것이 이상적입니다.

나는 preg_replace 또는 htmlspecialchars보다 나은 것을 찾고 있습니다. DOMDocument::createTextNode()이 표시되지만 결과 DOMText 개체가 번거로워서 DOMDocument::createElement()으로 넘길 수 없습니다.

는이 코드를 문제를 설명하기 위해 :

<?php 

$dom = new DOMDocument; 
$dom->formatOutput = true; 
$parent = $dom->createElement('rootNode'); 
$parent->appendChild($dom->createElement('name', 'this ampersand causes pain & sorrow ')); 
$dom->appendChild($parent); 
echo $dom->saveXml(); 

이 결과를 생성 (eval.in 참조)

Warning: DOMDocument::createElement(): unterminated entity reference   sorrow in /tmp/execpad-41ee778d3376/source-41ee778d3376 on line 6 
<?xml version="1.0"?> 
<rootNode> 
    <name>this ampersand causes pain </name> 
</rootNode> 
+0

"preg_replace이다 또는 반드시 htmlspecialchars보다 더 나은"- 어떤면에서 더 나은? – bobdye

+0

preg_replace 및 htmlspecialchars는 광역 스펙트럼 도구입니다. preg_replace 접근법은 XML 문자 문제에 대한 개발자의 지식에 완전히 의존합니다. htmlspecialcharacters 접근법은 논쟁의 여지가 있습니다 (http://stackoverflow.com/questions/2822774/php-is-htmlentities-sufficient-for-creating-xml-safe-values). 그리고이 문제는 XML에 특유한 것이므로 XML 라이브러리가이를 처리 할 수있는 명확한 방법을 제공 할 것으로 기대합니다. – doub1ejack

답변

2

당신은 텍스트 노드를 만들고를 추가해야합니다. 이 대답에 문제를 설명했습니다 : DOMDocumentcreateElement*()을 확장 할 수 있지만이 문제의 대답은 https://stackoverflow.com/a/22957785/2265374

입니다.

class MyDOMDocument extends DOMDocument { 

    public function createElement($name, $content = '') { 
    $node = parent::createElement($name); 
    if ((string)$content !== '') { 
     $node->appendChild($this->createTextNode($content)); 
    } 
    return $node; 
    } 

    public function createElementNS($namespace, $name, $content = '') { 
    $node = parent::createElementNS($namespace, $name); 
    if ((string)$content !== '') { 
     $node->appendChild($this->createTextNode($content)); 
    } 
    return $node; 
    } 
} 

$dom = new MyDOMDocument(); 
$root = $dom->appendChild($dom->createElement('foo')); 
$root->appendChild($dom->createElement('bar', 'Company & Son')); 
$root->appendChild($dom->createElementNS('urn:bar', 'bar', 'Company & Son')); 

$dom->formatOutput = TRUE; 
echo $dom->saveXml(); 

출력 :

<?xml version="1.0"?> 
<foo> 
    <bar>Company &amp; Son</bar> 
    <bar xmlns="urn:bar">Company &amp; Son</bar> 
</foo> 
+0

그리고 유감스럽게도 [documentation] (http://php.net/manual/en/domdocument.createelement.php)에서도 이렇게 말합니다 : _ 값은 이스케이프되지 않습니다. 이스케이프 지원을 사용하여 텍스트 노드를 만들려면 DOMDocument :: createTextNode()를 사용하십시오. – Scuzzy

+1

메모가 정확하지 않습니다. 이스케이프 처리됩니다. https://eval.in/278921 – ThW

0

이 내가 XML 요소를 구축하는 데 사용하는 구조가, 두 번째 부분은 일반적으로 기능에 싸여있다.

$parent = $document->documentElement; // pick the node we want to append to 
$name = 'foo'; // new element name 
$content = 'bar < not a tag > <![CDATA[" testing cdata "]]>'; // content 

$element = ($parent->ownerDocument) ? $parent->ownerDocument->createElement($name) : $parent->createElement($name); 
$parent->appendchild($element); 
$element->appendchild($parent->ownerDocument->createTextNode($content)); 

내 작동합니다 다음 return $element