tek4

Xử lý file XML trong PHP

by - September. 21, 2021
Kiến thức
Học
<p>Trong b&agrave;i viết n&agrave;y, ta sẽ c&ugrave;ng t&igrave;m hiểu về c&aacute;ch thức xử l&yacute; file XML trong PHP bằng c&aacute;c tr&igrave;nh ph&acirc;n t&iacute;ch file XML kh&aacute;c nhau c&ugrave;ng với v&iacute; dụ dẫn chứng.</p> <h1>Xử l&yacute; file XML trong PHP</h1> <p>Ng&ocirc;n ngữ XML l&agrave; một c&aacute;ch để x&acirc;y dựng cấu tr&uacute;c cho dữ liệu để chia sẻ tr&ecirc;n c&aacute;c trang Web. XML rất dễ c&oacute; thể tạo. N&oacute; rất giống với HTML, nhưng ta c&oacute; thể tạo c&aacute;c thẻ của ri&ecirc;ng m&igrave;nh bằng ng&ocirc;n ngữ XML n&agrave;y.</p> <p>Để đọc v&agrave; cập nhật, tạo v&agrave; thao t&aacute;c một t&agrave;i liệu XML, ta sẽ cần một tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p XML. Trong PHP, c&oacute; hai loại tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p XML ch&iacute;nh:</p> <ol> <li>Tr&igrave;nh ph&acirc;n t&iacute;ch dựa tr&ecirc;n cấu tr&uacute;c c&acirc;y (Tree-Based Parsers)</li> <li>Tr&igrave;nh ph&acirc;n t&iacute;ch dựa tr&ecirc;n sự kiện (Event-Based Parsers)</li> </ol> <h2>1. Tr&igrave;nh ph&acirc;n t&iacute;ch dựa tr&ecirc;n cấu tr&uacute;c c&acirc;y (Tree-Based Parsers)</h2> <p>Tree-Based Parsers sẽ giữ to&agrave;n bộ t&agrave;i liệu trong bộ nhớ v&agrave; chuyển t&agrave;i liệu XML th&agrave;nh cấu tr&uacute;c c&acirc;y. N&oacute; ph&acirc;n t&iacute;ch to&agrave;n bộ t&agrave;i liệu v&agrave; cung cấp quyền truy cập v&agrave;o c&aacute;c phần tử c&acirc;y (DOM).</p> <p>Loại tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p n&agrave;y ph&ugrave; hợp với c&aacute;c t&agrave;i liệu XML c&oacute; k&iacute;ch thước nhỏ. V&iacute; dụ về tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p dựa tr&ecirc;n cấu tr&uacute;c c&acirc;y:</p> <ul> <li>SimpleXML</li> <li>DOM</li> </ul> <h2>2. Tr&igrave;nh ph&acirc;n t&iacute;ch dựa theo sự kiện (Event-Based Parsers)</h2> <p>C&aacute;c tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p dựa tr&ecirc;n sự kiện kh&ocirc;ng giữ to&agrave;n bộ t&agrave;i liệu trong bộ nhớ, thay v&agrave;o đ&oacute;, ch&uacute;ng đọc trong một n&uacute;t tại một thời điểm v&agrave; cho ph&eacute;p ta tương t&aacute;c trong thời gian thực. Khi ta chuyển sang n&uacute;t tiếp theo, n&uacute;t cũ sẽ bị loại bỏ. Loại tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p n&agrave;y rất ph&ugrave; hợp cho c&aacute;c t&agrave;i liệu XML c&oacute; k&iacute;ch thước lớn. N&oacute; ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p nhanh hơn v&agrave; sử dụng &iacute;t bộ nhớ hơn.</p> <p>V&iacute; dụ về tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p dựa tr&ecirc;n sự kiện:</p> <ul> <li>XMLReader</li> <li>XML Expat Parser</li> </ul> <h2>3. Tr&igrave;nh ph&acirc;n t&iacute;ch SimpleXML</h2> <p>SimpleXML l&agrave; một tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p dựa tr&ecirc;n cấu tr&uacute;c c&acirc;y. SimpleXML cung cấp một c&aacute;ch dễ d&agrave;ng để lấy t&ecirc;n, thuộc t&iacute;nh v&agrave; nội dung văn bản của phần tử nếu ta biết cấu tr&uacute;c hoặc bố cục của t&agrave;i liệu XML. SimpleXML chuyển một t&agrave;i liệu XML th&agrave;nh một cấu tr&uacute;c dữ liệu m&agrave; ta c&oacute; thể duyệt qua giống như một tập hợp c&aacute;c mảng v&agrave; đối tượng.</p> <p>So với DOM hoặc tr&igrave;nh ph&acirc;n t&iacute;ch c&uacute; ph&aacute;p Expat, SimpleXML sử dụng &iacute;t đoạn m&atilde; hơn.</p> <p>Từ PHP 5, c&aacute;c h&agrave;m SimpleXML l&agrave; một phần của phần ch&iacute;nh PHP. Kh&ocirc;ng cần c&agrave;i đặt để sử dụng c&aacute;c h&agrave;m n&agrave;y.</p> <h3>3.1. Đọc chuỗi</h3> <p>H&agrave;m simplexml_load_string() trong PHP được sử dụng để đọc dữ liệu XML từ một chuỗi.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $vi_du = "&lt;?xml version='1.0' encoding='UTF-8'?&gt; &lt;mail&gt; &lt;hello&gt;Xin chao&lt;/hello&gt; &lt;body&gt;Lap trinh PHP!&lt;/body&gt; &lt;/mail&gt;"; $vi_du2 = simplexml_load_string($vi_du) or die("Lỗi"); print_r($vi_du2); ?&gt;</pre> <p>Kết quả:</p> <pre>SimpleXMLElement Object ( [hello] =&gt; Xin chao [body] =&gt; Lap trinh PHP! )</pre> <h3>3.2 Đọc từ file XML</h3> <p>H&agrave;m simplexml_load_file() được sử dụng để đọc dữ liệu XML từ một file với đu&ocirc;i l&agrave; php.</p> <p>Giả sử ta c&oacute; một file với t&ecirc;n l&agrave; tek4.xml c&oacute; nội dung như sau:</p> <pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;mail&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;hello&gt;Xin chao&lt;/hello&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;body&gt;Lap trinh PHP!&lt;/body&gt; &lt;/mail&gt;</pre> <p>Ta sẽ thực hiện việc đọc file XML bằng đoạn m&atilde; b&ecirc;n dưới đ&acirc;y.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $a=simplexml_load_file("tek4.xml") or die("Lỗi"); print_r($a); ?&gt;</pre> <p>Kết quả:</p> <pre>SimpleXMLElement Object ( [hello] =&gt; Xin chao [body] =&gt; Lap trinh PHP! )</pre> <h3>3.3 Truy cập v&agrave;o c&aacute;c gi&aacute; trị của nh&aacute;nh từ file XML</h3> <p>V&iacute; dụ 1: Giả sử ta c&oacute; nội dung file t&ecirc;n tek4.xml như sau.</p> <pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;mail&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;hello&gt;Xin chao&lt;/hello&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;body&gt;Lap trinh PHP!&lt;/body&gt; &lt;/mail&gt;</pre> <p>Ta sẽ truy cập v&agrave;o c&aacute;c nh&aacute;nh như sau.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $a=simplexml_load_file("tek4.xml") or die("Lỗi"); echo $a -&gt; hello . "&lt;br&gt;"; echo $a -&gt; body . "&lt;br&gt;"; ?&gt;</pre> <p>Kết quả:</p> <pre>Xin chao Lap trinh PHP!</pre> <p>V&iacute; dụ 2: Giả sử ta c&oacute; file tek4.xml với nội dung như sau.</p> <pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;sinh_vien&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen A&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;1&lt;/ID&gt; &nbsp; &lt;/sv&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen B&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;2&lt;/ID&gt; &nbsp; &lt;/sv&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen C&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;3&lt;/ID&gt; &nbsp; &lt;/sv&gt; &lt;/sinh_vien&gt;</pre> <p>Ta sẽ in ra th&ocirc;ng tin của c&aacute;c sinh vi&ecirc;n như sau.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $xml=simplexml_load_file("tek4.xml") or die("Lỗi"); foreach($xml-&gt;children() as $sv) { &nbsp; echo $sv-&gt;ID . ", "; &nbsp; echo $sv-&gt;Ten; &nbsp; echo "&lt;br&gt;"; } ?&gt;</pre> <p>Kết quả:</p> <pre>1, Nguyen A 2, Nguyen B 3, Nguyen C</pre> <p>Ngo&agrave;i ra để in ra thuộc t&iacute;nh của c&aacute;c phần tử sv, ta sẽ sử dụng dấu ngoặc vu&ocirc;ng v&agrave; để t&ecirc;n thuộc t&iacute;nh trong dấu nh&aacute;y đơn [&lsquo;t&ecirc;n thuộc t&iacute;nh&rsquo;] v&agrave; thực hiện đoạn m&atilde; như sau:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $xml=simplexml_load_file("tek4.xml") or die("Lỗi"); foreach($xml-&gt;children() as $sv) { &nbsp; echo $sv['type']; &nbsp; echo "&lt;br&gt;"; } ?&gt;</pre> <p>Kết quả:</p> <pre>Sinh vien Sinh vien Sinh vien</pre> <h2>4. Tr&igrave;nh ph&acirc;n t&iacute;ch XMLReader</h2> <p>XMLReader được sử dụng để đọc v&agrave; truy xuất nội dung của c&aacute;c file XML, bằng c&aacute;ch sử dụng c&aacute;c phương thức của lớp XMLReader, ta c&oacute; thể đọc từng n&uacute;t của c&aacute;c file XML.</p> <p>Trong phần n&agrave;y, ta sẽ sử dụng một file tek4.xml c&oacute; nội dung như sau:</p> <pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;sinh_vien&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen A&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;1&lt;/ID&gt; &nbsp; &lt;/sv&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen B&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;2&lt;/ID&gt; &nbsp; &lt;/sv&gt; &nbsp; &lt;sv type ="Sinh vien"&gt; &nbsp;&nbsp;&nbsp; &lt;Ten&gt;Nguyen C&lt;/Ten&gt; &nbsp;&nbsp;&nbsp; &lt;ID&gt;3&lt;/ID&gt; &nbsp; &lt;/sv&gt; &lt;/sinh_vien&gt;</pre> <h3>4.1 Mở file XML</h3> <p>H&agrave;m XMLReader::open() của lớp XMLReader nhận một gi&aacute; trị chuỗi biểu thị đường dẫn của file XML m&agrave; c&oacute; nội dung sẽ được đọc.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $Xmlread = new XMLReader(); $check = $Xmlread-&gt;open("tek4.xml"); if ($check){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; echo "Tệp được mở"; } else{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; echo "Tệp kh&ocirc;ng được mở"; } $Xmlread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Tệp được mở</pre> <h3>4.2 Đ&oacute;ng file</h3> <p>H&agrave;m XMLReader::close() của lớp XMLReader được sử dụng để đ&oacute;ng đối tượng hiện tại đang được ph&acirc;n t&iacute;ch.</p> <p>Ta sẽ thực hiện việc đọc nội dung của file bằng đoạn m&atilde; b&ecirc;n dưới như sau.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $Xmlread = new XMLXmlread(); $Xmlread-&gt;open("tek4.xml"); while($Xmlread-&gt;next()){ &nbsp;&nbsp;&nbsp; print($Xmlread-&gt;readString()); } $Xmlread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Nguyen A 1 Nguyen B 2 Nguyen C 3</pre> <p>Sau khi đọc nội dung của file tek4.xml, ta sẽ thực hiện việc đ&oacute;ng đối tượng $Xmlread.</p> <h3>4.3 Lấy gi&aacute; trị thuộc t&iacute;nh</h3> <p>H&agrave;m XMLReader::getAttribute() của lớp XMLReader nhận một gi&aacute; trị chuỗi k&yacute; tự m&agrave; biểu thị t&ecirc;n của một thuộc t&iacute;nh v&agrave; trả về gi&aacute; trị của n&oacute;.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $Xmlread = new XMLReader(); $Xmlread-&gt;open("tek4.xml"); while($Xmlread-&gt;read()){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $val = $Xmlread-&gt;getAttribute('type'); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print($val."\n"); } $Xmlread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Sinh vien Sinh vien Sinh vien Sinh vien Sinh vien Sinh vien</pre> <p>Trong file tek4.xml, ta c&oacute; c&aacute;c thẻ sv chứa thuộc t&iacute;nh t&ecirc;n l&agrave; type. Do đ&oacute;, ta sẽ lấy thuộc t&iacute;nh n&agrave;y v&agrave; in ra gi&aacute; trị của thuộc t&iacute;nh n&agrave;y.</p> <p>Ngo&agrave;i ra, ta c&oacute; thể lấy gi&aacute; trị thuộc t&iacute;nh bằng h&agrave;m XMLReader::getAttributeNo() của lớp XMLReader, h&agrave;m n&agrave;y nhận một gi&aacute; trị số nguy&ecirc;n đại diện cho chỉ số của một thuộc t&iacute;nh v&agrave; trả về gi&aacute; trị của n&oacute;.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $Xmlread = new XMLReader(); $Xmlread-&gt;open("tek4.xml"); while($Xmlread-&gt;read()){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $val = $Xmlread-&gt;getAttributeNo(0); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print($val."\n"); } $Xmlread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Sinh vien Sinh vien Sinh vien Sinh vien Sinh vien Sinh vien</pre> <h3>4.4 Di chuyển tới n&uacute;t tiếp theo</h3> <p>H&agrave;m XMLReader::next() c&oacute; nhiệm vụ di chuyển con trỏ tr&ecirc;n tệp XML hiện tại đến n&uacute;t tiếp theo.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $Xmlread = new XMLReader(); $Xmlread-&gt;open("tek4.xml"); while($Xmlread-&gt;next()){ &nbsp;&nbsp; print($Xmlread-&gt;readString()); } $Xmlread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Nguyen A 1 Nguyen B 2 Nguyen C 3</pre> <h3>4.5 Đọc nội dung</h3> <p>H&agrave;m XMLReader::readString() được sử dụng để đọc nội dung của n&uacute;t hiện tại v&agrave; trả về ch&uacute;ng dưới dạng một chuỗi.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $XMLread = new XMLReader(); $XMLread-&gt;open("tek4.xml"); while($XMLread-&gt;next()){ &nbsp;&nbsp; print($XMLread-&gt;readString()); } $XMLread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Nguyen A 1 Nguyen B 2 Nguyen C 3</pre> <h3>4.6 H&agrave;m XML()</h3> <p>H&agrave;m XMLReader::XML() của lớp XMLReader nhận một gi&aacute; trị chuỗi k&yacute; tự biểu thị nội dung của XML dưới dạng tham số v&agrave; thực hiện ph&acirc;n t&iacute;ch n&oacute;.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $XMLread = new XMLReader(); $a = "&lt;sinh_vien&gt; &lt;sv type ='Sinh vien'&gt; &nbsp; &lt;Ten&gt;Nguyen A&lt;/Ten&gt; &nbsp; &lt;ID&gt;1&lt;/ID&gt; &lt;/sv&gt; &lt;sv type ='Sinh vien'&gt; &nbsp; &lt;Ten&gt;Nguyen B&lt;/Ten&gt; &nbsp; &lt;ID&gt;2&lt;/ID&gt; &lt;/sv&gt; &lt;sv type ='Sinh vien'&gt; &nbsp; &lt;Ten&gt;Nguyen C&lt;/Ten&gt; &nbsp; &lt;ID&gt;3&lt;/ID&gt; &lt;/sv&gt; &lt;/sinh_vien&gt;"; $XMLread-&gt;xml($a); while($XMLread-&gt;next()){ &nbsp;&nbsp; print($XMLread-&gt;readString()); } $XMLread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Nguyen A 1 Nguyen B 2 Nguyen C 3</pre> <h3>4.7 H&agrave;m readInnerXml()</h3> <p>H&agrave;m XMLReader::readInnerXml() l&agrave; một h&agrave;m c&oacute; sẵn trong PHP được sử dụng để đọc nội dung của n&uacute;t hiện tại, bao gồm c&aacute;c n&uacute;t con.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $XMLread = new XMLReader(); $XMLread-&gt;open('tek4.xml'); $XMLread-&gt;read(); $XMLread-&gt;read(); $XMLread-&gt;read(); echo $XMLread-&gt;readInnerXml(); $XMLread-&gt;close(); ?&gt;</pre> <p>Kết quả:</p> <pre>Nguyen A&nbsp;1</pre> <p>Tr&ecirc;n đ&acirc;y l&agrave; kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về xử l&yacute; file XML trong PHP. Hy vọng mọi người c&oacute; thể &aacute;p dụng v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i tiếp theo v&agrave; cập nhật c&aacute;c b&agrave;i mới nhất tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p> <p>P/s: Cảm ơn mọi người!</p>