출력 - PHP로 XML 문서 생성(이스케이프 문자)




xml 이스케이프 문자 (7)

XML 엔터티 문제를 해결하기 위해 열심히 노력, 이런 식으로 해결 :

htmlspecialchars($value, ENT_QUOTES, 'UTF-8')

PHP 스크립트에서 XML 문서를 생성 중이며 XML 특수 문자를 이스케이프 처리해야합니다. 이스케이프해야하는 문자 목록을 알고 있습니다. 하지만 올바른 방법은 무엇입니까?

역 슬래시 (\ ')로 문자를 이스케이프 처리해야합니까? 아니면 적절한 방법입니까? 나를 위해 이것을 처리 할 수있는 내장 된 PHP 함수가 있습니까?


XML에있는 5 개의 "미리 정의 된 엔터티"로 이스케이프 처리하는 간단한 함수를 만들었습니다.

function xml_entities($string) {
    return strtr(
        $string, 
        array(
            "<" => "&lt;",
            ">" => "&gt;",
            '"' => "&quot;",
            "'" => "&apos;",
            "&" => "&amp;",
        )
    );
}

사용 예제 Demo :

$text = "Test &amp; <b> and encode </b> :)";
echo xml_entities($text);

산출:

Test &amp;amp; &lt;b&gt; and encode &lt;/b&gt; :)

유사한 효과는 str_replace 를 사용하여 얻을 수 있지만 double-replacings (테스트되지 않았거나 권장되지 않음) 때문에 깨지기 쉽습니다.

function xml_entities($string) {
    return str_replace(
        array("&",     "<",    ">",    '"',      "'"),
        array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;"), 
        $string
    );
}


유효한 최종 XML 텍스트를 얻으려면 모든 XML 엔터티를 이스케이프 처리하고 XML 문서 처리 명령에서 설명한 텍스트와 동일한 인코딩으로 텍스트를 작성해야합니다 ( <?xml 줄의 "인코딩"). 악센트 부호가있는 문자는 문서로 인코딩 된 경우 이스케이프 할 필요가 없습니다.

그러나 htmlspecialchars 입력을 이스케이프하면 단순히 인코딩 된 엔티티 (예 : &eacute;&amp;eacute; )가 될 수 있으므로 HTML 엔티티를 먼저 디코딩하는 것이 좋습니다.

function xml_escape($s)
{
    $s = html_entity_decode($s, ENT_QUOTES, 'UTF-8');
    $s = htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
    return $s;
}

이제 모든 강조 문자가 XML 문서 인코딩에서 유효한지 확인해야합니다. 모든 XML 파서가 XML 문서 처리 명령 인코딩을 존중하지는 않기 때문에 XML 출력을 UTF-8로 항상 인코딩하는 것이 좋습니다. 당신의 입력이 다른 문자 세트에서 온 것이라면, utf8_encode() 사용해보십시오.

ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252 및 KOI8-R - PHP는 이들을 모두 다음과 같이 취급합니다. 동일하지만 아이콘에는 약간의 차이가 있습니다. 일부는 iconv() 도 처리 할 수 ​​없습니다. utf8_encode() 비헤비어를 보완하면이 인코딩 문제 만 해결할 수 있습니다.

function encode_utf8($s)
{
    $cp1252_map = array(
    "\xc2\x80" => "\xe2\x82\xac",
    "\xc2\x82" => "\xe2\x80\x9a",
    "\xc2\x83" => "\xc6\x92",
    "\xc2\x84" => "\xe2\x80\x9e",
    "\xc2\x85" => "\xe2\x80\xa6",
    "\xc2\x86" => "\xe2\x80\xa0",
    "\xc2\x87" => "\xe2\x80\xa1",
    "\xc2\x88" => "\xcb\x86",
    "\xc2\x89" => "\xe2\x80\xb0",
    "\xc2\x8a" => "\xc5\xa0",
    "\xc2\x8b" => "\xe2\x80\xb9",
    "\xc2\x8c" => "\xc5\x92",
    "\xc2\x8e" => "\xc5\xbd",
    "\xc2\x91" => "\xe2\x80\x98",
    "\xc2\x92" => "\xe2\x80\x99",
    "\xc2\x93" => "\xe2\x80\x9c",
    "\xc2\x94" => "\xe2\x80\x9d",
    "\xc2\x95" => "\xe2\x80\xa2",
    "\xc2\x96" => "\xe2\x80\x93",
    "\xc2\x97" => "\xe2\x80\x94",
    "\xc2\x98" => "\xcb\x9c",
    "\xc2\x99" => "\xe2\x84\xa2",
    "\xc2\x9a" => "\xc5\xa1",
    "\xc2\x9b" => "\xe2\x80\xba",
    "\xc2\x9c" => "\xc5\x93",
    "\xc2\x9e" => "\xc5\xbe",
    "\xc2\x9f" => "\xc5\xb8"
    );
    $s=strtr(utf8_encode($s), $cp1252_map);
    return $s;
}

적절한 이스케이프 처리는 정확한 XML 출력을 얻는 방법이지만 속성요소에 대해 다르게 이스케이프 처리해야합니다. (토마스의 답변이 잘못되었습니다.)

나는 애트리뷰트와 엘리먼트 이스케이프 사이를 구별 짓는 자바 코드를 작성 / 훔쳤다. 그 이유는 XML 파서가 특히 공백에있는 모든 공백을 고려하기 때문입니다.

PHP로 포팅하는 것은 쉽습니다 (Tomas Jancik의 접근법을 위의 적절한 이스케이프와 함께 사용할 수 있음). UTF-8 사용하는 경우 확장 된 엔티티를 이스케이프 처리하는 것에 대해 걱정할 필요가 없습니다.

내 Java 코드를 포팅하고 싶지 않다면 스트림 기반 XMLWriter 를 살펴보고 libxml을 사용하여 매우 효율적이어야합니다.


htmlspecialchars() 함수는 어떻습니까?

htmlspecialchars($input, ENT_QUOTES | ENT_XML1, $encoding);

참고 : ENT_XML1 플래그는 PHP 5.4.0 이상인 경우에만 사용할 수 있습니다.

이 매개 변수를 사용하는 htmlspecialchars() 는 다음 문자를 대체합니다.

  • & (앰퍼샌드)는 &amp;
  • " (큰 따옴표)는 &quot;
  • ' (작은 따옴표)는 &apos;
  • < (미만)은 &lt;
  • > (보다 큼)은 &gt;

get_html_translation_table() 함수를 사용하여 변환 테이블을 가져올 수 있습니다.


 function replace_char($arr1)
 {
  $arr[]=preg_replace('>','&gt', $arr1); 
  $arr[]=preg_replace('<','&lt', $arr1);
  $arr[]=preg_replace('"','&quot', $arr1);
  $arr[]=preg_replace('\'','&apos', $arr1);
  $arr[]=preg_replace('&','&amp', $arr1);

  return $arr;
  }       






xml