> php教程 > PHP开发 > 본문

PHP가 XML을 구문 분석하는 네 가지 방법에 대한 자세한 소개

高洛峰
풀어 주다: 2017-01-06 15:16:38
원래의
1172명이 탐색했습니다.

PHP가 xml을 구문 분석하는 네 가지 방법

XML 처리는 개발 과정에서 자주 발생하며 PHP도 이에 대한 풍부한 지원을 제공합니다. 이 기사에서는 일부 구문 분석 기술에 대해서만 간략하게 설명합니다. , 포함: Xml 파서, SimpleXML, XMLReader, DOMDocument.

1. XML Expat 파서:

XML 파서는 Expat XML 파서를 사용합니다. Expat는 XML 문서를 일련의 이벤트로 처리하는 이벤트 기반 파서입니다. 이벤트가 발생하면 지정된 함수를 호출하여 이를 처리합니다. Expat는 문서에 연결된 모든 DTD를 무시하는 검증이 필요 없는 파서입니다. 그러나 문서의 형식이 좋지 않으면 오류 메시지가 표시됩니다. 이벤트 기반이고 유효성 검사가 없기 때문에 Expat는 빠르고 웹 애플리케이션에 적합합니다.

XML Parser의 장점은 XML 문서 전체를 메모리에 올려서 처리하는 것이 아니라, 파싱하면서 처리하기 때문에 성능이 좋다는 것입니다. 그러나 바로 이 때문에 XML 구조를 동적으로 조정하거나 XML 컨텍스트 구조를 기반으로 복잡한 작업을 수행해야 하는 사용자에게는 적합하지 않습니다. 잘 구성된 XML 문서를 구문 분석하고 처리하려는 경우 작업을 잘 완료할 수 있습니다. XML Parser는 US-ASCII, ISO-8859-1 및 UTF-8의 세 가지 인코딩 형식만 지원합니다. XML 데이터가 다른 인코딩으로 되어 있는 경우 먼저 위 세 가지 중 하나로 변환해야 합니다.
일반적으로 XML Parser에 일반적으로 사용되는 두 가지 구문 분석 방법(실제로는 두 가지 기능)이 있습니다: xml_parse_into_struct 및 xml_set_element_handler.

xml_parse_into_struct

이 방법은 xml 데이터를 두 개의 배열로 구문 분석합니다.

인덱스 배열 - 값 배열의 값 위치에 대한 포인터를 포함합니다.
값 배열 - 구문 분석된 XML의 데이터를 포함합니다.

이 두 배열은 텍스트로 설명하기가 다소 번거로우므로 예를 살펴보겠습니다(공식 PHP 문서에서 참조).

$simple = "<para><note>simple note</note></para>";
$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
로그인 후 복사

출력 :

Index array
Array
(
  [PARA] => Array
    (
      [0] => 0
      [1] => 2
    )
 
  [NOTE] => Array
    (
      [0] => 1
    )
)
 
Vals array
Array
(
  [0] => Array
    (
      [tag] => PARA
      [type] => open
      [level] => 1
    )
 
  [1] => Array
    (
      [tag] => NOTE
      [type] => complete
      [level] => 2
      [value] => simple note
    )
 
  [2] => Array
    (
      [tag] => PARA
      [type] => close
      [level] => 1
    )
)
로그인 후 복사

인덱스 배열은 키로 명명하고 해당 값은 값 배열에 이 태그의 위치를 ​​모두 포함하는 배열입니다. 그런 다음 이 위치를 통해 이 레이블에 해당하는 값을 찾습니다.

xml의 각 데이터 집합의 형식이 다르고 완전히 통합할 수 없는 경우 코드를 작성할 때 주의해야 하며 잘못된 결과가 나올 수 있습니다. 예를 들어, 다음의 예는

$xml = &#39;
<infos>
<para><note>note1</note><extra>extra1</extra></para>
<para><note>note2</note></para>
<para><note>note3</note><extra>extra3</extra></para>
</infos>
&#39;;
 
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $values, $tags);
xml_parser_free($p);
$result = array();
로그인 후 복사
//下面的遍历方式有bug隐患
for ($i=0; $i<3; $i++) {
 $result[$i] = array();
 $result[$i]["note"] = $values[$tags["NOTE"][$i]]["value"];
 $result[$i]["extra"] = $values[$tags["EXTRA"][$i]]["value"];
}
print_r($result);
로그인 후 복사

위의 방법으로 트래버스하면 코드는 단순해 보이지만 숨겨진 위험이 있습니다. 가장 치명적인 것은 잘못된 결과를 얻는 것입니다(extra3). 내부의 두 번째 파라로 실행됩니다). 따라서 좀 더 엄격한 방식으로 탐색해야 합니다.

$result = array();
$paraTagIndexes = $tags[&#39;PARA&#39;];
$paraCount = count($paraTagIndexes);
for($i = 0; $i < $paraCount; $i += 2) {
 $para = array();
 //遍历para标签对之间的所有值
 for($j = $paraTagIndexes[$i]; $j < $paraTagIndexes[$i+1]; $j++) {
  $value = $values[$j][&#39;value&#39;];
  if(empty($value)) continue;
 
  $tagname = strtolower($values[$j][&#39;tag&#39;]);
  if(in_array($tagname, array(&#39;note&#39;,&#39;extra&#39;))) {
   $para[$tagname] = $value;
  }
 }
 $result[] = $para;
}
로그인 후 복사

사실 저는 xml_parse_into_struct 함수를 거의 사용하지 않으므로 위의 소위 "엄격한" 코드가 유지되지 않으면 버그가 생길 수 있습니다. 다른 상황. - -|

xml_set_element_handler

파서가 요소의 시작과 끝을 처리하도록 콜백 함수를 설정하는 방법입니다. 또한 파서에 대한 데이터를 설정하는 데 사용되는 콜백 함수 xml_set_character_data_handler도 포함되어 있습니다. 이런 방식으로 작성된 코드는 더 명확하고 유지 관리가 더 쉽습니다.

예:

$xml = <<<XML
<infos>
<para><note>note1</note><extra>extra1</extra></para>
<para><note>note2</note></para>
<para><note>note3</note><extra>extra3</extra></para>
</infos>
XML;
 
$result = array();
$index = -1;
$currData;
 
function charactor($parser, $data) {
 global $currData;
 $currData = $data;
}
 
function startElement($parser, $name, $attribs) {
 global $result, $index;
 $name = strtolower($name);
 if($name == &#39;para&#39;) {
  $index++;
  $result[$index] = array();
 }
}
 
function endElement($parser, $name) {
 global $result, $index, $currData;
 $name = strtolower($name);
 if($name == &#39;note&#39; || $name == &#39;extra&#39;) {
  $result[$index][$name] = $currData;
 }
}
 
$xml_parser = xml_parser_create();
xml_set_character_data_handler($xml_parser, "charactor");
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!xml_parse($xml_parser, $xml)) {
 echo "Error when parse xml: ";
 echo xml_error_string(xml_get_error_code($xml_parser));
}
xml_parser_free($xml_parser);
 
print_r($result);
로그인 후 복사

set 핸들러 메소드는 코드 라인이 많지만 아이디어가 명확하고 가독성이 좋지만 성능이 처음보다 약간 느린 것을 볼 수 있습니다. 매우 유연하지 않습니다. XML 파서는 PHP4를 지원하며 이전 버전을 사용하는 시스템에 적합합니다. PHP5 환경에서는 다음 방법을 우선적으로 사용하세요.

2. SimpleXML

SimpleXML은 PHP5 이후에 제공되는 간단하고 사용하기 쉬운 XML 도구 세트입니다. XML을 처리하기 편리한 객체로 변환할 수 있고, XML 데이터를 구성하고 생성할 수도 있습니다. 단, 네임스페이스를 포함하는 xml에는 적용되지 않으며, xml은 올바른 형식이어야 합니다. simplexml_import_dom, simplexml_load_file, simplexml_load_string의 세 가지 메소드를 제공합니다. 함수 이름을 보면 직관적으로 함수를 알 수 있습니다. 세 가지 함수 모두 SimpleXMLElement 개체를 반환하며 SimpleXMLElement 작업을 통해 데이터를 읽거나 추가합니다. <… . 작은 파일을 읽는 중이고 xml에 네임스페이스가 없으면 SimpleXML이 좋은 선택입니다.

$string = <<<XML
<?xml version=&#39;1.0&#39;?>
<document>
 <cmd>login</cmd>
 <login>imdonkey</login>
</document>
XML;
 
$xml = simplexml_load_string($string);
print_r($xml);
$login = $xml->login;//这里返回的依然是个SimpleXMLElement对象
print_r($login);
$login = (string) $xml->login;//在做数据比较时,注意要先强制转换
print_r($login);
로그인 후 복사
3. XMLReader

XMLReader는 PHP5 이후의 확장 기능입니다(5.1 이후 기본적으로 설치됨). 문서 흐름에서 커서처럼 이동하고 각 노드에서 중지됩니다. 이는 입력에 대한 빠르고 캐시되지 않은 스트리밍 액세스를 제공하며, 스트림이나 문서를 읽을 수 있어 사용자가 여기에서 데이터를 추출하고 애플리케이션에 의미가 없는 레코드를 건너뛸 수 있습니다.

Google Weather API를 사용하여 정보를 얻는 예는 XMLReader의 사용을 보여줍니다. 여기에는 소수의 기능만 포함되어 있으므로 공식 문서를 참조하세요.

XMLReader와 XML Parser는 유사하며 둘 다 읽는 동안 작동합니다. 가장 큰 차이점은 SAX 모델이 분석기가 이벤트를 실행할 때마다 애플리케이션에 푸시하는 "푸시" 모델이라는 점입니다. reads 새 노드를 가져오면 응용 프로그램에 알림이 전송되고 XmlReader를 사용하는 응용 프로그램은 더 나은 제어성을 통해 마음대로 판독기에서 노드를 추출할 수 있습니다.

XMLReader는 libxml을 기반으로 하기 때문에 일부 기능에 대한 설명서를 참조하여 libxml 버전에 적용 가능한지 확인해야 합니다.
$xml_uri = &#39;http://www.google.com/ig/api?weather=Beijing&hl=zh-cn&#39;;
$current = array();
$forecast = array();
 
$reader = new XMLReader();
$reader->open($xml_uri, &#39;gbk&#39;);
while ($reader->read()) {
 //get current data
 if ($reader->name == "current_conditions" && $reader->nodeType == XMLReader::ELEMENT) {
  while($reader->read() && $reader->name != "current_conditions") {
   $name = $reader->name;
   $value = $reader->getAttribute(&#39;data&#39;);
   $current[$name] = $value;
  }
 }
 
 //get forecast data
 if ($reader->name == "forecast_conditions" && $reader->nodeType == XMLReader::ELEMENT) {
  $sub_forecast = array();
  while($reader->read() && $reader->name != "forecast_conditions") {
   $name = $reader->name;
   $value = $reader->getAttribute(&#39;data&#39;);
   $sub_forecast[$name] = $value;
  }
  $forecast[] = $sub_forecast;
 }
}
$reader->close();
로그인 후 복사

4. DOMDocument

DOMDocument는 PHP5 이후에 출시된 DOM 확장의 일부이기도 합니다. 이는 html/xml을 생성하거나 구문 분석하는 데 사용할 수 있습니다. 현재는 utf-8 인코딩만 지원합니다.

$xmlstring = <<<XML
<?xml version=&#39;1.0&#39;?>
<document>
 <cmd attr=&#39;default&#39;>login</cmd>
 <login>imdonkey</login>
</document>
XML;
 
$dom = new DOMDocument();
$dom->loadXML($xmlstring);
print_r(getArray($dom->documentElement));
 
function getArray($node) {
 $array = false;
 
 if ($node->hasAttributes()) {
  foreach ($node->attributes as $attr) {
   $array[$attr->nodeName] = $attr->nodeValue;
  }
 }
 
 if ($node->hasChildNodes()) {
  if ($node->childNodes->length == 1) {
   $array[$node->firstChild->nodeName] = getArray($node->firstChild);
  } else {
   foreach ($node->childNodes as $childNode) {
   if ($childNode->nodeType != XML_TEXT_NODE) {
    $array[$childNode->nodeName][] = getArray($childNode);
   }
  }
 }
 } else {
  return $node->nodeValue;
 }
 return $array;
}
로그인 후 복사

从函数名上看感觉跟JavaScript很像,应该是借鉴了一些吧。DOMDocument也是一次性将xml载入内存,所以内存问题同样需要注意。PHP提供了这么多的xml处理方式,开发人员在选择上就要花些时间了解,选择适合项目需求及系统环境、又便于维护的方法。

感谢阅读,希望能帮助到大家,谢谢大家对本站支持!

更多php 解析xml 的四种方法详细介绍相关文章请关注PHP中文网!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!