xml을 PHP 파일에로드하는 동안 'xmlParseEntityRef : 이름 없음'경고가 표시됨


89

을 사용하여 PHP에서 xml을 읽고 simplexml_load_file있습니다. 그러나 xml을로드하는 동안 경고 목록이 표시됩니다.

Warning: simplexml_load_file() [function.simplexml-load-file]: <project orderno="6" campaign_name="International Relief & Development" project in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Warning: simplexml_load_file() [function.simplexml-load-file]: ional Relief & Development" project_id="313" client_name="International Relief & in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

이러한 경고를 제거하려면 어떻게해야합니까?

(XML은 URL에서 생성되고 http://..../index.php/site/projectstest.php의 변수에로드됩니다. index.php에 대한 쓰기 권한이 없습니다.)


XML이 잘못되었습니다. 전혀로드하지 못할 수도 있습니다. 플래그 @앞에 simplexml_load_file추가하거나 플래그를 추가하여 오류를 억제 할 수 있습니다. simplexml_load_file자세한 내용 은의 매뉴얼 페이지를 참조하고 질문을 삭제하십시오. 중복입니다.
hakre

제 답변이 상당히 많은 관심을 받고 있음을 알 수 있습니다. 이것이 실제로 해결책이라면 "정답"으로 표시해 주시겠습니까? 감사.
ricricucit 2014 년

답변:


143

XML은 대부분 유효하지 않습니다.

문제는 "&"일 수 있습니다.

$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $text);

"&"를 제거하고 HTML 코드 버전으로 대체합니다. 시도해보십시오.


2
감사합니다. 당신은 내 하루를 구했습니다!
Saim

2
XML로 작업하면서 가장 좋은 방법은 충돌하는 문자가 없는지 확인하는 것입니다 그리고 당신은 parsin 전에 교체해야합니다
미스터 메가 마인드

2
감사합니다.이 질문의 요점은 xml이 유효하지 않기 때문입니다
yussan

약간의 추가로 모든 앰퍼샌드를 바꾸려면 정규식에 'g'를 추가하십시오. 업데이트 된 솔루션은 다음과 같습니다. $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

80

여기 에서 찾았 습니다 ...

문제점 : XML 구문 분석기가 "xmlParseEntityRef : noname"오류를 리턴합니다.

원인 : XML 텍스트 어딘가에 '&'(앰퍼샌드 문자)가 있습니다. 일부 텍스트 및 추가 텍스트

해결책:

  • 해결 방법 1 : 앰퍼샌드를 제거합니다.
  • 해결 방법 2 : 앰퍼샌드를 인코딩합니다 (즉, &문자 를로 대체 &amp;). XML 텍스트를 읽을 때 디코딩해야합니다.
  • 솔루션 3 : CDATA 섹션을 사용합니다 (CDATA 섹션 내부의 텍스트는 파서에 의해 무시됩니다.) 예. <! [CDATA [일부 텍스트 및 추가 텍스트]]>

참고 : '&' '<' '>'는 올바르게 처리되지 않으면 모두 문제가됩니다.


9
이것은 오늘 나를 구했습니다.
Bwire 2014-06-16

그 이유를 알고 있습니까? 또한이 데이터의 일부를 렌더링하는 브라우저에서 CDATA 섹션을 계속 선택합니까? XML 태그 내부에 HTML 태그가 있으며 편집 도구를 위해 최종 사용자에게 렌더링해야합니다.
sulimmesh

11

이 기능을 사용하여 먼저 HTML을 정리하십시오.

$html = htmlspecialchars($html);

특수 문자는 일반적으로 HTML에서 다르게 표현되며 컴파일러에게 혼동을 줄 수 있습니다. 처럼 &됩니다 &amp;.


누군가 이것이 왜 반대 투표인지 설명 할 수 있습니까? 요소 데이터의 문자 htmlspecialchars()를 변환하는 정확한 함수 &, ", <, >입니다.
JacobRossDev

7
이 답변은이 경우 잘 작동하지 않기 때문에 반대 투표입니다. 이 함수를 사용하면 "<"를 "& lt;"로 변환하여 XML을 완전히 깨뜨릴 수 있습니다. htmlspecialchars()XML을 깨뜨리지 않고 사용할 수있는 방법을 알지 못합니다 . 몇 가지 플래그를 시도했지만 XML이 여전히 손상되었습니다.
Alex Finnarn

1
당신은 사용해야 htmlspecialchars하지 전체 XML에 XML 태그의 내용에
gbalduzzi

7

결합 된 버전을 사용합니다.

strip_tags(preg_replace("/&(?!#?[a-z0-9]+;)/", "&amp;",$textorhtml))

1
이것은 완벽하게 작동합니다. 당신은 단지 끝 오른쪽 대괄호를 놓치고
myh34d

7

문제

  • URL에서 XML 파일을로드하는 동안 PHP 함수에서 simplexml_load_file구문 분석 오류가 발생 parser error : xmlParseEntityRef합니다.

원인

  • URL에서 반환 된 XML은 유효한 XML이 아닙니다. &대신 값을 포함 합니다 &amp;. 이 시점에서 분명하지 않은 다른 오류가있을 수 있습니다.

우리가 통제 할 수없는 것들

  • 이상적으로는 유효한 XML이 PHP simplexml_load_file함수에 제공 되는지 확인해야 하지만 XML 생성 방법을 제어 할 수없는 것처럼 보입니다.
  • simplexml_load_file유효하지 않은 XML 파일 을 강제 로 처리 할 수도 없습니다 . XML 파일 자체를 수정하는 것 외에는 많은 옵션이 남지 않습니다.

가능한 해결책

잘못된 XML을 유효한 XML로 변환합니다. 을 사용하여 수행 할 수 있습니다 PHP tidy extension. 추가 지침은 http://php.net/manual/en/book.tidy.php 에서 찾을 수 있습니다 .

확장이 존재하거나 설치되었는지 확인한 후 다음을 수행하십시오.

/**
 * As per the question asked, the URL is loaded into a variable first, 
 * which we can assume to be $xml
 */
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<project orderno="6" campaign_name="International Relief & Development for under developed nations">
    <invalid-data>Some other data containing & in it</invalid-data>
    <unclosed-tag>
</project>
XML;

/**
 * Whenever we use tidy it is best to pass some configuration options 
 * similar to $tidyConfig. In this particular case we are making sure that
 * tidy understands that our input and output is XML.
 */
$tidyConfig = array (
    'indent' => true,
    'input-xml' => true, 
    'output-xml' => true,
    'wrap' => 200
);

/**
 * Now we can use tidy to parse the string and then repair it.
 */
$tidy = new tidy;
$tidy->parseString($xml, $tidyConfig, 'utf8');
$tidy->cleanRepair();

/**
 * If we try to output the repaired XML string by echoing $tidy it should look like. 

 <?xml version="1.0" encoding="utf-8"?>
 <project orderno="6" campaign_name="International Relief &amp; Development for under developed nations">
      <invalid-data>Some other data containing &amp; in it</invalid-data>
      <unclosed-tag></unclosed-tag>
 </project> 

 * As you can see that & is now fixed in campaign_name attribute 
 * and also with-in invalid-data element. You can also see that the   
 * <unclosed-tag> which didn't had a close tag, has been fixed too.
 */
echo $tidy;

/**
 * Now when we try to use simplexml_load_string to load the clean XML. When we
 * try to print_r it should look something like below.

 SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [orderno] => 6
            [campaign_name] => International Relief & Development for under developed nations
        )

    [invalid-data] => Some other data containing & in it
    [unclosed-tag] => SimpleXMLElement Object
        (
        )

)

 */
 $simpleXmlElement = simplexml_load_string($tidy);
 print_r($simpleXmlElement);

주의

개발자는 tidy를 사용한 후 부작용이 없는지 확인하기 위해 잘못된 XML을 유효한 XML (tidy에 의해 생성됨)과 비교해야합니다. Tidy는이를 올바르게 수행하는 데 매우 효과적이지만 시각적으로보고 100 % 확신하는 것은 결코 아프지 않습니다. 우리의 경우 $ xml과 $ tidy를 비교하는 것만 큼 간단해야합니다.



3

이것은 문자가 데이터를 엉망으로 만들었 기 때문입니다. 사용 htmlentities($yourText)나를 위해 일한 (필자는 XML 문서 내부의 HTML 코드를했다). http://uk3.php.net/htmlentities를 참조하십시오 .


1

이것은 내 문제를 해결합니다.

$description = strip_tags($value['Description']);
$description=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $description);
$description= preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $description);
$description=str_replace(' & ', ' &amp; ', html_entity_decode((htmlspecialchars_decode($description))));

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.