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

PHP 動態產生 XML 並解析轉 HTML 完整實作 (不使用 DOM)

     編輯:PHP 相關知識

架構說明

  • 資料來源:MySQL books 資料表
  • 產生 XML:PHP 字串拼接 (無 DOM)
  • 儲存 XML:寫入檔案 xmldoc/xmldoc.xml
  • 解析 XML:xml_parser_create() (SAX 事件驅動) 解析並輸出 HTML

1. 資料表結構

CREATE TABLE books (
    bookid INT(4) NOT NULL AUTO_INCREMENT,
    bookname VARCHAR(100) NOT NULL,
    bookauth VARCHAR(50) NOT NULL,
    bookpublisher VARCHAR(50) NOT NULL,
    bookpubdate DATETIME NOT NULL,
    bookurl VARCHAR(50) NOT NULL,
    PRIMARY KEY (bookid)
);

2. MySQL → XML 產生腳本 generate_xml.php

<?php
$conn = mysql_connect('localhost', 'root', '');
mysql_select_db('bbs', $conn);

$query = "SELECT * FROM books ORDER BY bookid";
$rs = mysql_query($query, $conn);
$numFields = mysql_num_fields($rs);

$xml = '<?xml version="1.0" encoding="GB2312"?> ';
$xml .= '<books> ';

while ($row = mysql_fetch_array($rs)) {
    for ($i = 0; $i < $numFields; $i++) {
        $fieldName = mysql_field_name($rs, $i);
        // 注意:欄位值需跳脫 XML 特殊字元
        $value = htmlspecialchars($row[$i], ENT_QUOTES, 'GB2312');
        $xml .= "<$fieldName>$value</$fieldName> ";
    }
}

mysql_free_result($rs);
mysql_close($conn);

$xml .= '</books> ';

$fp = fopen('xmldoc/xmldoc.xml', 'w');
if (fwrite($fp, $xml)) {
    echo "XML 檔案寫入成功!";
} else {
    echo "寫入失敗!";
}
fclose($fp);
?>

注意:原始碼未對值做 htmlspecialchars,實務必加上防止 <, >, & 破壞 XML 結構。

3. XML → HTML 解析腳本 parse_xml.php (SAX 解析器)

<?php
class XMLParser {
    var $parser;
    var $currentTag = '';
    var $currentData = '';
    var $books = [];
    var $currentBook = [];

    function __construct($xmlFile) {
        $this->parser = xml_parser_create();
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, 'startElement', 'endElement');
        xml_set_character_data_handler($this->parser, 'characterData');
        
        $data = file_get_contents($xmlFile);
        if (!xml_parse($this->parser, $data)) {
            die(sprintf("XML 錯誤: %s at line %d",
                xml_error_string(xml_get_error_code($this->parser)),
                xml_get_current_line_number($this->parser)
            ));
        }
        xml_parser_free($this->parser);
        $this->outputHtml();
    }

    function startElement($parser, $name, $attrs) {
        $this->currentTag = $name;
        if ($name === 'bookid') {
            $this->currentBook = [];
        }
    }

    function characterData($parser, $data) {
        if ($this->currentTag && $this->currentTag !== 'books') {
            $this->currentBook[$this->currentTag] = $data;
        }
    }

    function endElement($parser, $name) {
        if ($name === 'bookid') {
            $this->books[] = $this->currentBook;
        }
        $this->currentTag = '';
    }

    function outputHtml() {
        echo "<table border='1' cellpadding='5' cellspacing='0'>";
        echo "<tr><th>ID</th><th>書名</th><th>作者</th><th>出版社</th><th>出版日期</th><th>連結</th></tr>";
        foreach ($this->books as $book) {
            echo "<tr>";
            echo "<td>" . htmlspecialchars($book['bookid']) . "</td>";
            echo "<td>" . htmlspecialchars($book['bookname']) . "</td>";
            echo "<td>" . htmlspecialchars($book['bookauth']) . "</td>";
            echo "<td>" . htmlspecialchars($book['bookpublisher']) . "</td>";
            echo "<td>" . htmlspecialchars($book['bookpubdate']) . "</td>";
            echo "<td><a href='" . htmlspecialchars($book['bookurl']) . "' target='_blank'>連結</a></td>";
            echo "</tr>";
        }
        echo "</table>";
    }
}

new XMLParser('xmldoc/xmldoc.xml');
?>

SAX vs DOM 解析器比較

特性SAX (xml_parser)DOM (DOMDocument)
記憶體極低 (串流)載入整份文件
速度快較慢
API 風格事件驅動 (callback)樹狀物件操作
適合場景大型 XML、單向讀取需隨機存取、修改、XPath 查詢
錯誤處理需自行處理libxml_use_internal_errors()

現代替代方案:XMLReader (Pull Parser, PHP 5.1+)

<?php
$reader = new XMLReader();
$reader->open('xmldoc/xmldoc.xml');

echo "<table border='1'><tr><th>ID</th><th>書名</th><th>作者</th><th>出版社</th><th>日期</th><th>連結</th></tr>";

while ($reader->read()) {
    if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === 'bookid') {
        // 讀取完整  節點
        $bookXml = $reader->readOuterXml();
        $bookDom = new DOMDocument();
        $bookDom->loadXML($bookXml);
        
        $id = $bookDom->getElementsByTagName('bookid')->item(0)->textContent;
        $name = $bookDom->getElementsByTagName('bookname')->item(0)->textContent;
        $auth = $bookDom->getElementsByTagName('bookauth')->item(0)->textContent;
        $pub = $bookDom->getElementsByTagName('bookpublisher')->item(0)->textContent;
        $date = $bookDom->getElementsByTagName('bookpubdate')->item(0)->textContent;
        $url = $bookDom->getElementsByTagName('bookurl')->item(0)->textContent;
        
        echo "<tr><td>$id</td><td>$name</td><td>$auth</td><td>$pub</td><td>$date</td><td><a href='$url'>連結</a></td></tr>";
    }
}
echo "</table>";
$reader->close();
?>

優點:記憶體效率如 SAX,API 如 DOM 直觀,支援 readOuterXml() 取得片段再交給 DOM 處理。

總結

本文展示「MySQL → 字串拼接 XML → 檔案 → SAX 解析 → HTML」完整流程。雖然字串拼接 XML 簡單,但生產環境強烈建議使用 DOMDocument 或 XMLWriter 產生 XML,自動處理編碼、跳脫、格式化。解析端則視檔案大小與需求選擇 SAX (大檔/單向)、DOM (小檔/隨機存取) 或 XMLReader (折衷)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved