2008-10-09 43 views
122

Tôi đã sử dụng trình phân tích cú pháp XML trước đây, và mặc dù nó hoạt động OK, tôi không hài lòng với nó nói chung, cảm thấy như tôi đang sử dụng cách giải quyết cho những thứ cần phải là chức năng cơ bản.Trình phân tích cú pháp XML tốt nhất cho PHP

Gần đây tôi đã thấy SimpleXML nhưng chưa thử. Có đơn giản hơn không? Cả hai lợi thế và bất lợi đều có? Bạn đã sử dụng bất kỳ trình phân tích cú pháp nào khác không?

+3

Gợi ý cho bất kỳ ai đọc câu hỏi này: đặt câu hỏi mô tả những gì bạn cần * làm * với XML (ngoài việc phân tích cú pháp nó) và bạn có thể sẽ nhận được câu trả lời tốt hơn nhiều. – Shog9

+2

Vui lòng xem câu hỏi tham khảo chung sau đây cho thẻ PHP: ** [Cách phân tích và xử lý HTML/XML bằng PHP?] (Http://stackoverflow.com/questions/3577641/how-to-parse-and-process -html-xml-with-php) ** – hakre

Trả lời

87

Tôi sẽ phải nói SimpleXML lấy bánh vì trước tiên nó là phần mở rộng, được viết bằng C và rất nhanh. Nhưng thứ hai, tài liệu được phân tích cú pháp có dạng của một đối tượng PHP. Vì vậy, bạn có thể "truy vấn" như $root->myElement.

+12

simplexml là tốt nhất. Nhưng không phải là làm việc tốt với các không gian tên, nó đôi khi có thể gặp khó khăn – pleasedontbelong

+2

Vâng, tôi nghĩ nó tốt nhất. Và tôi sử dụng xpath với nó. $ xml-> xpath ("// block"); // ĐÂY LÀ SIÊU :) – Vahan

+5

Tôi không nghĩ là tốt nhất. Nó không hỗ trợ xml phiên bản = "1.1" và ném cảnh báo về thực tế này (phiên bản PHP của tôi là 5.3.6). Tôi biết rằng bạn có thể tắt cảnh báo và nó hoạt động tốt, nhưng tôi không nghĩ đó là một giải pháp tốt. Vì vậy, hãy tưởng tượng điều gì sẽ xảy ra, nếu nhà cung cấp API của bạn thay đổi phiên bản tài liệu xml từ 1.0 đến 1.1? Thứ hai nghĩ là những gì @Gordon chỉ ra. SimpleXML tải toàn bộ tài liệu vào bộ nhớ. Đó là giải pháp tốt nhưng chắc chắn không tốt nhất. – Karol

11

Tùy thuộc vào những gì bạn đang cố gắng thực hiện với các tệp XML. Nếu bạn chỉ đang cố gắng đọc tệp XML (như tệp cấu hình), Wicked Flea là chính xác trong việc đề xuất SimpleXML vì nó tạo ra số tiền cho các ArrayObject lồng nhau. ví dụ. giá trị sẽ được truy cập bởi $ xml-> root-> child.

Nếu bạn đang tìm kiếm để thao tác các tập tin XML có lẽ bạn đang giảm giá tốt nhất sử dụng DOM XML

38

Hãy nhìn vào PHP available XML extensions và xem http://devzone.zend.com/243/http://devzone.zend.com/1035/ cho một cuộc thảo luận về những.

Sự khác biệt chính giữa XML Parser và SimpleXML là sau này không phải là trình phân tích cú pháp kéo. SimpleXML được xây dựng trên phần mở rộng của DOM và sẽ tải toàn bộ tệp XML vào bộ nhớ. Trình phân tích cú pháp XML như XMLReader sẽ chỉ tải nút hiện tại vào bộ nhớ. Bạn xác định các trình xử lý cho các nút cụ thể sẽ được kích hoạt khi Trình phân tích cú pháp gặp phải. Đó là nhanh hơn và tiết kiệm trên bộ nhớ. Bạn trả tiền cho điều đó với việc không thể sử dụng XPath.

Cá nhân, tôi thấy SimpleXml khá hạn chế (do đó đơn giản) trong những gì nó cung cấp qua DOM. Bạn có thể chuyển đổi giữa DOM và SimpleXml một cách dễ dàng, nhưng tôi thường không bận tâm và đi trực tiếp vào tuyến đường DOM. DOM là việc triển khai API DOM của W3C, vì vậy bạn có thể quen thuộc với nó từ các ngôn ngữ khác, ví dụ như JavaScript.

21

Đây là một chức năng hữu ích cho nhanh chóng và dễ dàng phân tích cú pháp xml khi một phần mở rộng không có sẵn:

<?php 
/** 
* Convert XML to an Array 
* 
* @param string $XML 
* @return array 
*/ 
function XMLtoArray($XML) 
{ 
    $xml_parser = xml_parser_create(); 
    xml_parse_into_struct($xml_parser, $XML, $vals); 
    xml_parser_free($xml_parser); 
    // wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie 
    $_tmp=''; 
    foreach ($vals as $xml_elem) { 
     $x_tag=$xml_elem['tag']; 
     $x_level=$xml_elem['level']; 
     $x_type=$xml_elem['type']; 
     if ($x_level!=1 && $x_type == 'close') { 
      if (isset($multi_key[$x_tag][$x_level])) 
       $multi_key[$x_tag][$x_level]=1; 
      else 
       $multi_key[$x_tag][$x_level]=0; 
     } 
     if ($x_level!=1 && $x_type == 'complete') { 
      if ($_tmp==$x_tag) 
       $multi_key[$x_tag][$x_level]=1; 
      $_tmp=$x_tag; 
     } 
    } 
    // jedziemy po tablicy 
    foreach ($vals as $xml_elem) { 
     $x_tag=$xml_elem['tag']; 
     $x_level=$xml_elem['level']; 
     $x_type=$xml_elem['type']; 
     if ($x_type == 'open') 
      $level[$x_level] = $x_tag; 
     $start_level = 1; 
     $php_stmt = '$xml_array'; 
     if ($x_type=='close' && $x_level!=1) 
      $multi_key[$x_tag][$x_level]++; 
     while ($start_level < $x_level) { 
      $php_stmt .= '[$level['.$start_level.']]'; 
      if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level]) 
       $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']'; 
      $start_level++; 
     } 
     $add=''; 
     if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) { 
      if (!isset($multi_key2[$x_tag][$x_level])) 
       $multi_key2[$x_tag][$x_level]=0; 
      else 
       $multi_key2[$x_tag][$x_level]++; 
      $add='['.$multi_key2[$x_tag][$x_level].']'; 
     } 
     if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) { 
      if ($x_type == 'open') 
       $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];'; 
      else 
       $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];'; 
      eval($php_stmt_main); 
     } 
     if (array_key_exists('attributes', $xml_elem)) { 
      if (isset($xml_elem['value'])) { 
       $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];'; 
       eval($php_stmt_main); 
      } 
      foreach ($xml_elem['attributes'] as $key=>$value) { 
       $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;'; 
       eval($php_stmt_att); 
      } 
     } 
    } 
    return $xml_array; 
} 
?> 
+0

hoạt động như một nét duyên dáng, trong đó simpleXml không thành công trong một vài tập lệnh mà tôi đang làm, nhờ –

+0

nhận được thông báo lỗi: Biến không xác định: xml_array? – shfkktm

0

phân tích cú pháp crxml là một thực dễ dàng để phân tích cú pháp.

Lớp này có hàm tìm kiếm, có tên nút với bất kỳ không gian tên nào làm đối số. Nó tìm kiếm xml cho nút và in ra câu lệnh truy cập để truy cập nút đó bằng cách sử dụng lớp này. Lớp này cũng làm cho việc tạo xml rất dễ dàng.

bạn có thể tải về lớp này tại

http://freshmeat.net/projects/crxml

hoặc từ phpclasses.org

http://www.phpclasses.org/package/6769-PHP-Manipulate-XML-documents-as-array.html

+9

Có thể bạn sẽ muốn tiết lộ rằng bạn là tác giả của lớp này. –

+0

PHPClasses.org vẫn là một điều? Chỉnh sửa: Ồ, tôi đoán nó vẫn còn trong '11 –

14

Hi Tôi nghĩ rằng SimpleXML là rất hữu ích. Và với nó tôi đang sử dụng xpath;

$xml = simplexml_load_file("som_xml.xml"); 

$blocks = $xml->xpath('//block'); //gets all <block/> tags 
$blocks2 = $xml->xpath('//layout/block'); //gets all <block/> which parent are <layout/> tags 

Tôi sử dụng nhiều cấu hình xml và điều này giúp tôi phân tích chúng thật nhanh. SimpleXml được viết trên C vì vậy nó rất nhanh.

Các vấn đề liên quan