Hướng dẫn
Quảng cáo

Cách tạo tài liệu XML bằng PHP

Bạn tạo tài liệu XML bằng PHP như thế nào? Cách nào để tạo tài liệu XML bằng PHP đơn giản và nhanh nhất? Hãy cùng xem nhé.

XML hoặc Ngôn ngữ đánh dấu mở rộng là định dạng tài liệu rất phổ biến thường được sử dụng cho các giao thức trao đổi dữ liệu giữa các máy, để lưu trữ dữ liệu, trong các dịch vụ web và cho nhiều mục đích sử dụng khác.

Nhiều ứng dụng web cần hoạt động với các tệp XML. Một số ví dụ bao gồm các dịch vụ web, AJAX và phần phụ trợ của ứng dụng từ xa cũng như các tập lệnh để lưu trữ hoặc truyền dữ liệu.

PHP có một số  công cụ khác nhau để xử lý các tệp XML. Trong bài đăng này, chúng ta sẽ xem cách tạo một tài liệu XML mới từ đầu bằng cách sử dụng ba phần mở rộng PHP khác nhau: SimpleXML , XMLWriter DOM .

Bạn nên sử dụng cái nào? Ưu và nhược điểm của mỗi cái là gì? Và cái nào nhanh hơn và hiệu quả hơn?

VÍ DỤ XML

Một tài liệu XML đơn giản trông như thế này:

Ví dụ

<?xml version=”1.0″ encoding=”UTF-8″?>
<Example>
   <node id=”1″ name=”node 1″>
      <subnode id=”1.1″ name=”subnode 1.1″/>
      <subnode id=”1.2″ name=”subnode 1.2″>
         <inner_node id=”1.2.1″ name=”inner node 1.2.1″/>
      </subnode>
   </node>
</Example>

Các tài liệu XML cũng có thể phức tạp hơn thế nhiều và bao gồm các phần tử đánh dấu khác (như không gian tên hoặc nhận xét), nhưng trong hướng dẫn này, chúng ta sẽ chỉ tập trung vào cách sao chép ví dụ cơ bản này và cách xử lý hai phần tử XML cơ bản nhất :  nút (nodes) và thuộc tính (attributes)

Mặc dù về mặt lý thuyết, chúng tôi chỉ có thể viết một tài liệu XML bằng cách sử dụng các hàm tiêu chuẩn (ví dụ: "lặp lại" tất cả các dòng thành một biến), nhưng đây chỉ là một tùy chọn hợp lệ nếu tài liệu chúng tôi cần tạo thực sự đơn giản và nếu chúng tôi biết chính xác dữ liệu nào. nó sẽ chứa.

Trong thực tế, hầu hết chúng ta sẽ cần tạo các tài liệu XML đọc dữ liệu từ một nơi nào đó (như cơ sở dữ liệu) và tự động thêm hoặc chỉnh sửa các nút và thuộc tính. Làm điều đó với các hàm chuỗi tiêu chuẩn là gần như không thể.

May mắn thay, PHP cung cấp cho chúng ta một số công cụ hữu ích để xử lý các tài liệu XML. Đầu tiên chúng ta sẽ thấy phần mở rộng SimpleXML và lớp chính của nó được gọi là SimpleXMLElement .

SimpleXML

Đúng như tên gọi, đây có lẽ là tiện ích mở rộng đơn giản và dễ hiểu nhất mà bạn có thể sử dụng để tạo tài liệu XML.

Đây là cách bạn có thể sử dụng lớp SimpleXMLElement để sao chép ví dụ trước:

Ví dụ

/* SimpleXML */
$xml_header = '<?xml version="1.0" encoding="UTF-8"?><Example></Example>';
$xml = new SimpleXMLElement($xml_header);
$node1 = $xml->addChild('node');
$node1->addAttribute('id', '1');
$node1->addAttribute('name', 'node 1');
$subnode1 = $node1->addChild('subnode');
$subnode1->addAttribute('id', '1.1');
$subnode1->addAttribute('name', 'subnode 1.1');
$subnode2 = $node1->addchild('subnode');
$subnode2->addAttribute('id', '1.2');
$subnode2->addAttribute('name', 'subnode 1.2');
$inner_node1 = $subnode2->addChild('inner_node');
$inner_node1->addAttribute('id', '1.2.1');
$inner_node1->addAttribute('name', 'inner node 1.2.1');
echo $xml->asXML();

Nhờ cú pháp đơn giản và mã dễ đọc, tiện ích mở rộng SimpleXML là một lựa chọn tốt nếu bạn chỉ cần thực hiện một số chỉnh sửa XML cơ bản.

Tuy nhiên, lớp này có một số nhược điểm. Trước hết, hàm tạo của lớp cần một tài liệu XML hiện có để làm việc, vì vậy chúng ta cần tự tạo nó theo cách thủ công. Đó là lý do tại sao chúng ta cần xác định biến $xml_header trước khi tạo đối tượng SimpleXMLElement trong đoạn mã trên.

Ngoài ra, tiện ích mở rộng này có thể không phải là lựa chọn tốt nhất nếu cần chỉnh sửa phức tạp hơn vì nó thiếu một số chức năng. Ví dụ: lớp SimpleXMLElement không có chức năng xóa các nút hiện có (bạn cần sử dụng chức năng bỏ đặt theo cách thủ công) và không thể xác thực tài liệu.

Hãy chắc chắn biết bạn sẽ cần thực hiện những thao tác nào trước khi quyết định sử dụng tiện ích mở rộng này cho dự án của mình và kiểm tra xem chúng có được hỗ trợ hay không.

Bây giờ chúng ta hãy xem cái tiếp theo.

 XMLWriter

Lớp XMLWriter thực sự là một trình bao bọc cho thư viện libxml. Điều nổi bật đầu tiên về lớp này là nó chỉ có thể được sử dụng để viết tài liệu ; nếu bạn cần đọc một tài liệu hiện có, bạn phải sử dụng lớp XMLReader hoặc sử dụng hoàn toàn một phần mở rộng XML khác.

Đây là mã để tạo tài liệu mẫu của chúng tôi với XMLWriter :

Ví dụ

$xml = new XMLWriter();
$xml->openURI('php://output');
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('Example');
$xml->startElement('node');
$xml->writeAttribute('id', '1');
$xml->writeAttribute('name', 'node 1');
$xml->startElement('subnode');
$xml->writeAttribute('id', '1.1');
$xml->writeAttribute('name', 'subnode 1.1');
$xml->endElement();
$xml->startElement('subnode');
$xml->writeAttribute('id', '1.2');
$xml->writeAttribute('name', 'subnode 1.2');
$xml->startElement('inner_node');
$xml->writeAttribute('id', '1.2.1');
$xml->writeAttribute('name', 'inner node 1.2.1');
$xml->endElement();
$xml->endElement();
$xml->endElement();
$xml->endElement();
$xml->flush();

Cú pháp của XMLWriter chắc chắn không phải là hay nhất và khá dài dòng. Mọi nút cần được mở bằng phương thức startElement và đóng bằng endElement . Khi có nhiều hơn một vài nút được lồng vào nhau, mã có thể dễ dàng khó đọc được.

Mặc dù không đẹp lắm nhưng lớp này cho phép bạn tạo hầu hết mọi phần tử XML bên trong tài liệu của mình, vì vậy nó có thể là lựa chọn tốt hơn SimpleXML để xử lý các cấu trúc XML phức tạp hơn.

Giới hạn chính của XMLWriter là cách tiếp cận thủ tục nghiêm ngặt của nó, đặc biệt là nó không cho phép bạn sửa đổi một phần tử XML sau khi nó đã được thêm vào cấu trúc của tài liệu . Điều này có nghĩa là, nếu bạn cần thêm một nút, bạn cần biết tất cả các thuộc tính của nó trước khi thêm nó, vì bạn không thể chỉnh sửa nó sau này.

Điều này có thể hoặc không thể là vấn đề đối với bạn, tùy thuộc vào dự án của bạn. Ngoài ra, không có gì ngăn cản bạn sử dụng cả XMLWriter và SimpleXML trên cùng một tài liệu (hoặc bất kỳ phần mở rộng XML nào khác), tất nhiên là không đồng thời. Ví dụ: bạn có thể quyết định tạo tài liệu từ đầu bằng XMLWriter (tận dụng hiệu suất và chức năng của nó) và chỉnh sửa nó sau bằng SimpleXML để thay đổi thuộc tính hoặc thêm nút mới.

Bây giờ hãy xem phần mở rộng cuối cùng.

MÔ HÌNH ĐỐI TƯỢNG TÀI LIỆU (DOM)

DOM là phần mở rộng PHP mạnh mẽ nhất để tạo và chỉnh sửa tài liệu XML. Bạn bắt đầu bằng cách tạo  đối tượng loại DomDocument làm tài liệu chính, sau đó tạo và thao tác nhiều nút dưới dạng  đối tượng DomElement .

Do đó, mọi thành phần tài liệu (nghĩa là chính tài liệu và mỗi nút) là một đối tượng riêng biệt và có thể được chỉnh sửa hoặc di chuyển bất kỳ lúc nào.

Đây là mã để tạo tài liệu mẫu của chúng tôi với DOM

Ví dụ

$xml = new DomDocument(‘1.0’, ‘UTF-8’);
$example_element = $xml->createElement(‘Example’);
$node1_element = $xml->createElement(‘node’);
$node1_element->setAttribute(‘id’, ‘1’);
$node1_element->setAttribute(‘name’, ‘node 1’);
$example_element->appendChild($node1_element);
$subnode1_element = $xml->createElement(‘subnode’);
$subnode1_element->setAttribute(‘id’, ‘1.1’);
$subnode1_element->setAttribute(‘name’, ‘subnode 1.1’);
$node1_element->appendChild($subnode1_element);
$subnode2_element = $xml->createElement(‘subnode’);
$subnode2_element->setAttribute(‘id’, ‘1.2’);
$subnode2_element->setAttribute(‘name’, ‘subnode 1.2’);
$node1_element->appendChild($subnode2_element);
$inner_node1_element = $xml->createElement(‘inner_node’);
$inner_node1_element->setAttribute(‘id’, ‘1.2.1’);
$inner_node1_element->setAttribute(‘name’, ‘inner node 1.2.1’);
$subnode2_element->appendChild($inner_node1_element);
$xml->appendChild($example_element);
$xml->formatOutput = TRUE;
echo $xml->saveXML();

Nếu bạn thích cấu trúc mã hướng đối tượng thì chắc chắn bạn sẽ thích cú pháp của DOM . DOM có thể là tiện ích mở rộng phù hợp để sử dụng nếu bạn cần tạo các tài liệu XML phức tạp, đặc biệt nếu bạn cần sửa đổi và mở rộng chúng một cách linh hoạt.

Vấn đề chính của DOM là hiệu suất tương đối kém đối với các tài liệu lớn.

Bây giờ hãy xem tất cả các tiện ích mở rộng này hoạt động như thế nào.

SO SÁNH HIỆU SUẤT

Để xử lý các tài liệu XML nhỏ, cả ba phần mở rộng này đều hoàn toàn có thể sử dụng được. Tuy nhiên, trong một số ứng dụng, có thể cần phải xử lý các tài liệu rất lớn, trong trường hợp đó hiệu suất của tiện ích mở rộng sẽ rất quan trọng.

Tôi đã chạy tập lệnh kiểm tra để tạo tài liệu XML nhiều lần trong một vòng lặp và cuối cùng kiểm tra thời gian thực thi (máy kiểm tra của tôi được định cấu hình bằng PHP 7.0). Tôi đã chạy thử nghiệm một vài lần để chắc chắn rằng kết quả là đáng tin cậy.

 Nếu bạn muốn tự mình chạy thử nghiệm, chỉ chạy file php với mã như dưới đây. 

Ví dụ

<?php


/* Choose which extension to test: SimpleXML, XMLWriter or DOM. */
const EXTENSION = 'SimpleXML';


const ITERATIONS = 2000;
set_time_limit(180);

$test = array('nodes' => 10, 'subnodes' => 10, 'sub-subnodes' => 10);
$start = microtime(TRUE);

for ($i = 0; $i < ITERATIONS; $i++)
{	
	if (EXTENSION === 'SimpleXML')
	{
		$xml_header = '<?xml version="1.0" encoding="UTF-8"?><Example></Example>';
		$xml = new SimpleXMLElement($xml_header);
		
		for ($a = 0; $a < $test['nodes']; $a++)
		{
			$node = $xml->addChild('node');
			$node->addAttribute('id', strval($a));
			
			for ($b = 0; $b < $test['subnodes']; $b++)
			{
				$subnode = $node->addChild('subnode');
				$subnode->addAttribute('id', strval($b));
				
				for ($c = 0; $c < $test['sub-subnodes']; $c++)
				{
					$sub_subnode = $subnode->addChild('sub-subnode');
					$sub_subnode->addAttribute('id', strval($c));
				}
			}
		}
		
		/* Uncomment the next lines to show the XML document and stop loop */
		// echo $xml->asXML();
		// die();
	}
	elseif (EXTENSION === 'XMLWriter')
	{
		$xml = new XMLWriter();
		$xml->openMemory();
		$xml->startDocument('1.0', 'UTF-8');
		$xml->startElement('Example');
		
		for ($a = 0; $a < $test['nodes']; $a++)
		{
			$xml->startElement('node');
			$xml->writeAttribute('id', strval($a));
			
			for ($b = 0; $b < $test['subnodes']; $b++)
			{
				$xml->startElement('subnode');
				$xml->writeAttribute('id', strval($b));
				
				for ($c = 0; $c < $test['sub-subnodes']; $c++)
				{
					$xml->startElement('sub-subnode');
					$xml->writeAttribute('id', strval($c));
					$xml->endElement();
				}
				
				$xml->endElement();
			}
			
			$xml->endElement();
		}
		
		$xml->endElement();
		
		/* Uncomment the next lines to show the XML document and stop loop */
		// echo $xml->outputMemory(TRUE);
		// die();
	}
	elseif (EXTENSION === 'DOM')
	{
		$xml = new DomDocument('1.0', 'UTF-8');
		$example_element = $xml->createElement('Example');
		
		for ($a = 0; $a < $test['nodes']; $a++)
		{
			$node_element = $xml->createElement('node');
			$node_element->setAttribute('id', strval($a));
			
			for ($b = 0; $b < $test['subnodes']; $b++)
			{
				$subnode_element = $xml->createElement('subnode');
				$subnode_element->setAttribute('id', strval($b));
				
				for ($c = 0; $c < $test['sub-subnodes']; $c++)
				{
					$sub_subnode_element = $xml->createElement('sub-subnode');
					$sub_subnode_element->setAttribute('id', strval($c));
					$subnode_element->appendChild($sub_subnode_element);
				}
				
				$node_element->appendChild($subnode_element);
			}
			
			$example_element->appendChild($node_element);
		}
		
		$xml->appendChild($example_element);
		
		/* Uncomment the next lines to show the XML document and stop loop */
		// $xml->formatOutput = TRUE;
		// echo $xml->saveXML();
		// die();
	}
}

$time = microtime(TRUE) - $start;
echo EXTENSION . ' ran in ' . strval(round($time, 2)) . ' seconds.';

 

Bài viết này đã giúp ích cho bạn?

Bài viết mới

Advertisements