本文提供一個純 PHP 實現的 XML 操作類,支持文檔聲明、根節點、屬性、子節點、CDATA 區塊的靈活構建,並提供文件保存與直接輸出功能。雖然現代項目推薦使用 DOMDocument 或 SimpleXML 內置擴展,但該類展示了手動拼接 XML 的核心邏輯,適合學習理解 XML 結構生成原理。
root())append_root_node()) 及屬性append_child_node()) 支持 CDATAappend_root_node_end())display())save())filter()) 防止非法字符破壞結構';
private $rssEnd = '';
public function __construct($version = '1.0', $encoding = 'UTF-8') {
$this->version = $version;
$this->encoding = $encoding;
}
public function newFile($filename) {
$this->filename = $filename;
return true;
}
public function root($element) {
$element = $this->filter($element);
if ($this->rootStart) {
throw new Exception('XML 只允許一個根元素');
}
$this->rootStart = "<{$element}>";
$this->rootEnd = "{$element}>";
$this->xml = "version}\" encoding=\"{$this->encoding}\" standalone=\"yes\"?>\n{$this->rssStart}\n{$this->rootStart}\n";
return true;
}
public function appendRootNode($title, $property = null, $proVal = null) {
$title = $this->filter($title);
$property = $this->filter($property);
$proVal = $this->filter($proVal);
$attr = $property ? " {$property}=\"{$proVal}\"" : '';
$this->xml .= "<{$title}{$attr}>\n";
$this->rootEnd = "{$title}>";
return true;
}
public function appendRootNodeEnd() {
$this->xml .= "{$this->rootEnd}\n";
return true;
}
public function appendChildNode($title = 'undefined', $content = 'undefined', $property = null, $proVal = null, $cdata = false) {
$title = $this->filter($title);
$content = $this->filter($content, false);
$property = $this->filter($property);
$proVal = $this->filter($proVal);
$attr = $property ? " {$property}=\"{$proVal}\"" : '';
if ($cdata) {
$this->xml .= "<{$title}{$attr}>{$title}>\n";
} else {
$this->xml .= "<{$title}{$attr}>{$content}{$title}>\n";
}
return true;
}
public function display() {
header("Content-Type: text/xml; charset={$this->encoding}");
echo $this->xml . $this->rootEnd . "\n" . $this->rssEnd;
}
public function save() {
$fullXml = $this->xml . $this->rootEnd . "\n" . $this->rssEnd;
$handle = fopen($this->filename, 'wb+');
$result = fwrite($handle, $fullXml);
fclose($handle);
if (!$result) {
throw new Exception("寫入文件失敗,請檢查目錄權限");
}
return true;
}
private function filter($string, $removeSpace = true) {
$filters = ['"', "'", "\n", "\r", "\t"];
if ($removeSpace) $filters[] = ' ';
return str_replace($filters, '', $string);
}
}
$xml = new XMLBuilder();
$xml->newFile('test.xml');
$xml->root('document');
$xml->appendRootNode('book');
$xml->appendChildNode('author', 'linage');
$xml->appendChildNode('page', 100);
$xml->appendChildNode('money', '35 RMB');
$xml->appendRootNodeEnd();
$xml->appendRootNode('book', 'name', 'The Web Servers');
$xml->appendChildNode('author', 'linage');
$xml->appendChildNode('page', 100);
$xml->appendChildNode('money', '35 RMB');
$xml->appendRootNodeEnd();
$xml->display(); // 瀏覽器直接查看
$xml->save(); // 保存文件
linage 100 35 RMB linage 100 35 RMB
| 方案 | 優勢 | 適用場景 |
|---|---|---|
| DOMDocument | W3C 標準、支持 XPath/Schema 驗證、大文件流式處理 | 企業級應用、複雜 XML 構建與解析 |
| SimpleXML | 語法極簡、屬性/節點像對象屬性一樣訪問、內存效率高 | 配置文件、API 響應快速生成 |
| XMLWriter | 流式寫入、內存佔用極低、性能最優 | 大體積 XML 導出、日誌流 |
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$rss = $dom->createElement('rss');
$rss->setAttribute('version', '2.0');
$dom->appendChild($rss);
$doc = $dom->createElement('document');
$rss->appendChild($doc);
$book = $dom->createElement('book');
$book->setAttribute('name', 'The Web Servers');
$doc->appendChild($book);
$author = $dom->createElement('author', 'linage');
$book->appendChild($author);
// ... 其他節點
echo $dom->saveXML();
手工拼接 XML 類適合教學與極簡場景,但缺乏對實體轉義、命名空間、Schema 驗證的完善支持。實際項目中請優先使用 DOMDocument 或 XMLWriter,確保輸出合規、安全且高效。