2012-12-20 2 views
6

에서 엔티티를 디코딩 나는 다음과 같은 문제가 발생 해요 :PHP, SimpleXML을은 CDATA

$xml_string1 = "<person><name><![CDATA[ Someone&#039;s Name ]]></name></person>"; 
$xml_string2 = "<person><name> Someone&#039;s Name </name></person>"; 

$person = new SimpleXMLElement($xml_string1); 
print (string) $person->name; # Someone&#039;s Name 

$person = new SimpleXMLElement($xml_string2); 
print (string) $person->name; # Someone's Name 

$person = new SimpleXMLElement($xml_string1, LIBXML_NOCDATA); 
print (string) $person->name; # Someone&#039;s Name 

는 PHP 문서는 NOCDATA는 "텍스트 노드로 [S] CDATA 병합"고 말한다. 나에게 이것은 CDATA가 텍스트 노드와 똑같이 취급된다는 것을 의미합니다 - 또는 3 번째 예제의 동작은 이제 2 번째 예제와 동일합니다. 그것은 아무것도하지 않고 내가 원하는 동작을 폐허로

내가 그렇지 않으면 난 그냥 CDATA 태그를 제거하는 것은 XML (은 외부 소스로부터의 공급이다)을 제어 할 수 없습니다.

이유는 위의 예는 수행하는 방식으로 작동 하는가? SimpleXML이 텍스트 노드를 처리하는 것과 같은 방법으로 CDATA 노드를 처리하도록하는 방법이 있습니까? 그 옵션을 이해하지 못하는 것 때문에 "CDATA를 텍스트 노드로 병합"하는 것은 실제로 무엇입니까? 내가 데이터를 꺼내 후

나는 현재 디코딩 합니다만, 위의 예는 여전히 나에게 이해가되지 않습니다.

+0

이 경우 문자열로 변환 할 필요가 없습니다. (더 일반적으로 echo''기록) – hakre

+0

@hakre하지만'print'는 다른 뭔가로 대체 디버깅하는 동안 독립에 사용 될 가능성이있다, 그래서 그것을 일관되게 문자열로 캐스팅 할 수있는 좋은 습관 말하고 싶지만 나중에 혼란을 피하십시오. – IMSoP

답변

9

XML에서 CDATA 섹션의 목적은 특수 문자 (특히 >, <&)가 이스케이프되어야하는 "있는 그대로"의 텍스트 블록을 캡슐화하는 것입니다. & 문자를 포함하는 CDATA 섹션 &amp;을 함유하는 일반 텍스트 노드와 동일하다.

파서는이를 무시하는 것을 제안하고, 즉시 즉시 누군가가 "P & O 크루즈"를 언급 한 바와 같이 휴식 것이, 모든 CDATA 노드 그냥 텍스트 노드 정말이었다 척한다면 - &은 단순히에있을 수 없다 자체 (&amp; 또는 &somethingElse;)가 아닙니다. (string)$foo 깔끔하게 일반 PHP 문자열로 텍스트와 CDATA 노드의 순서를 결합하기 때문에

LIBXML_NOCDATA 실제로 SimpleXML을 꽤 쓸모가 없다. (print_r하지 않기 때문에 사람들이 자주 실패 뭔가,주의한다.)이 반드시 같은 당신이 자신의 권리를 객체로 텍스트 노드 및 CDATA 노드를 조작 할 수있는 DOM 등보다 체계적인 접근 방법의 사실이 아니다.

CDATA 섹션에 도달하면 어디서나 내용을 가져와 이스케이프 처리하고 일반 텍스트 노드로 되돌 리거나 모든 텍스트 노드와 함께 "병합"합니다. 양쪽. 표현 된 텍스트는 동일하며 문서에 다른 방식으로 저장됩니다. 당신이 분석하고있는 XML 문서가 실제로 개체를 포함하는 CDATA 섹션을 포함

$xml_string = "<person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person>"; 

$person = new SimpleXMLElement($xml_string); 
echo 'CDATA retained: ', $person->asXML(); 
// CDATA retained: <?xml version="1.0"?> 
// <person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person> 

$person = new SimpleXMLElement($xml_string, LIBXML_NOCDATA); 
echo 'CDATA merged: ', $person->asXML(); 
// CDATA merged: <?xml version="1.0"?> 
// <person><name>Welcome aboard this P&amp;O Cruises voyage!</name></person> 

경우 해당 문자열과 언 이스케이프를 취할 필요 :이 예에서와 같이 XML에 다시 수출하는 경우 그 차이를 볼 수 있습니다 XML과 완전히 독립적입니다. 이것을 이해하는 일반적인 이유 중 하나는 HTML에서 마크 업 된 것을 뭔가 XML 문서 내의 오래된 문자열로 취급하는 것입니다. 예를 들면 다음과 같습니다 :

<Comment> 
<SubmittedBy>IMSoP</SubmittedBy> 
<Text><![CDATA[I'm <em>really</em> bad at keeping my answers brief <tt>;)</tt>]]></Text> 
</Comment> 
+1

위대한 답변, 매우 유익한 –