首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP XML 處理三大範式:DOM、SAX、Regex 讀寫全解析

     編輯:PHP 綜合知識

測試數據 test.xml

<?xml version="1.0" encoding="utf-8"?>
<books>
  <book>
    <author>Jack Herrington</author>
    <title>PHP Hacks</title>
    <publisher>O'Reilly</publisher>
  </book>
  <book>
    <author>Jack Herrington</author>
    <title>Podcasting Hacks</title>
    <publisher>O'Reilly</publisher>
  </book>
</books>

1. DOM 模式(樹結構,隨機訪問,適合中小文檔)

讀取

<?php
$doc = new DOMDocument();
$doc->load('test.xml');
foreach ($doc->getElementsByTagName('book') as $book) {
    $author   = $book->getElementsByTagName('author')->item(0)->nodeValue;
    $title    = $book->getElementsByTagName('title')->item(0)->nodeValue;
    $publisher= $book->getElementsByTagName('publisher')->item(0)->nodeValue;
    echo "Title: $title <br> Author: $author <br> Publisher: $publisher<hr>";
}
?>

寫入

<?php
$books = [
    ['title'=>'PHP Hacks', 'author'=>'Jack Herrington', 'publisher'=>"O'Reilly"],
    ['title'=>'Podcasting Hacks', 'author'=>'Jack Herrington', 'publisher'=>"O'Reilly"],
];
$doc = new DOMDocument();
$doc->formatOutput = true; // 縮進美化
$root = $doc->createElement('books');
$doc->appendChild($root);

foreach ($books as $b) {
    $book = $doc->createElement('book');
    foreach (['author','title','publisher'] as $tag) {
        $el = $doc->createElement($tag);
        $el->appendChild($doc->createTextNode($b[$tag]));
        $book->appendChild($el);
    }
    $root->appendChild($book);
}
$doc->save('books.xml'); // 或 echo $doc->saveXML();
?>

優點:API 直觀、自動保證 well-formed、支援 XPath。
缺點:需將整個文檔載入內存,大文檔易 OOM。

2. SAX 模式(流式事件驅動,低內存,適合大文檔)

<?php
$g_books = []; $g_elem = null;

function startElement($parser, $name, $attrs) {
    global $g_books, $g_elem;
    if ($name === 'BOOK') $g_books[] = [];
    $g_elem = $name;
}
function endElement($parser, $name) {
    global $g_elem; $g_elem = null;
}
function textData($parser, $text) {
    global $g_books, $g_elem;
    if (in_array($g_elem, ['AUTHOR','TITLE','PUBLISHER'])) {
        $g_books[count($g_books)-1][$g_elem] = $text;
    }
}

$parser = xml_parser_create();
xml_set_element_handler($parser, 'startElement', 'endElement');
xml_set_character_data_handler($parser, 'textData');

$fp = fopen('test.xml', 'r');
while ($data = fread($fp, 4096)) {
    xml_parse($parser, $data);
}
fclose($fp);
xml_parser_free($parser);

foreach ($g_books as $b) {
    echo "{$b['TITLE']} - {$b['AUTHOR']} - {$b['PUBLISHER']}\n";
}
?>

關鍵:$g_elem 追蹤當前標籤,$g_books 累積結果。內存佔用恆定,與文檔大小無關。

3. 正則表達式(不推薦生產環境,僅作兼容兜底)

<?php
$xml = file_get_contents('test.xml');
preg_match_all('/<book>(.*?)<\/book>/s', $xml, $blocks);
foreach ($blocks[1] as $block) {
    preg_match('/<author>(.*?)<\/author>/', $block, $a);
    preg_match('/<title>(.*?)<\/title>/', $block, $t);
    preg_match('/<publisher>(.*?)<\/publisher>/', $block, $p);
    echo "{$t[1]} - {$a[1]} - {$p[1]}\n";
}
?>

⚠️ 風險:屬性順序變更、CDATA、命名空間、巢狀標籤均會導致匹配失效。嚴禁解析不可信輸入。

4. 模板內嵌寫法(簡單場景快速輸出)

<?php
$books = [
    ['title'=>'PHP Hacks', 'author'=>'Jack Herrington', 'publisher'=>"O'Reilly"],
    ['title'=>'Podcasting Hacks', 'author'=>'Jack Herrington', 'publisher'=>"O'Reilly"],
];
?>
<books>
<?php foreach ($books as $b): ?>
  <book>
    <title><?= htmlspecialchars($b['title']) ?></title>
    <author><?= htmlspecialchars($b['author']) ?></author>
    <publisher><?= htmlspecialchars($b['publisher']) ?></publisher>
  </book>
<?php endforeach; ?>
</books>

注意:必須自行 htmlspecialchars 轉義,否則極易產生非法 XML。

選型建議

場景推薦理由
配置文件、RSS、API 響應(< 10MB)DOM / SimpleXML開發效率高,代碼可讀性強
海量數據導入/導出(> 100MB)SAX / XMLReader恆定內存,流式處理
極簡佈局、無屬性、可信輸入模板內嵌零依賴,直觀
歷史系統兼容、無擴展權限Regex(最後手段)僅作兜底,嚴加測試
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved