PHP读取和编写XML的四种实现方法

Jasper
Jasper
发布时间:2026-10-16 | 4人浏览过
原创

本文深入解析 PHP 处理 XML 数据的核心技术,涵盖 DOM 库的结构化读写、SAX 流式解析、正则匹配以及 PHP 与 HTML/XML 混合输出的多种方式,帮助开发者根据业务需求选择最优方案。

结果或目标

在实际开发中,PHP 需要频繁处理 XML 数据。无论是从现有 XML 文件中提取图书信息(标题、作者、出版社),还是动态生成规范的 XML 结构供前端或其他系统调用,选择合适的解析库至关重要。

准备条件

在开始之前,请确保服务器环境已启用 libxml 扩展(通常 PHP 默认安装)。为了便于演示,我们假设有一个名为 test.xml 的文件,其内容如下:

<?xml version="1.0" encoding="utf8"?>
<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步:使用 DOMDocument 读取 XML

目的: 获取 XML 中的结构化数据并输出。
入口: 初始化 DOMDocument 对象。
动作: 加载 XML 文件,遍历指定标签,提取节点值。
重要参数: load(), getElementsByTagName(), nodeValue。

这是最直观且常用的方式。代码首先创建一个新对象并加载 XML,随后获取所有 book 节点列表,循环提取子节点的文本内容。

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

第2步:使用 SAX 解析器读取 XML

目的: 通过事件驱动的方式解析 XML,适合处理大文件或仅需快速提取数据的场景。
入口: 创建解析器 xml_parser_create 并注册回调函数。
动作: 定义元素开始、结束和数据字符的处理函数,流式读取文件并解析。
重要参数: xml_set_element_handler, xml_set_character_data_handler.

SAX 不构建整个树结构,而是逐行扫描。当遇到开始标签时触发 startElement,结束标签触发 endElement,中间文字触发 textData。

$g_books = array();
$g_elem = null;

function startElement( $parser, $name, $attrs ){
    global $g_books, $g_elem;
    if ( $name == 'BOOK' ) $g_books[] = array();
    $g_elem = $name;
}

function endElement( $parser, $name ){
    global $g_elem;
    $g_elem = null;
}

function textData( $parser, $text ){
    global $g_books, $g_elem;
    if ( $g_elem == 'AUTHOR' || $g_elem == 'PUBLISHER' || $g_elem == 'TITLE' ){
        $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" );

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

xml_parser_free( $parser );

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

第3步:谨慎使用正则表达式解析 XML

目的: 快速获取简单的标签内容。
风险提示: 仅适用于格式固定且简单的 XML。严禁用于解析用户输入的不可控 XML,容易因嵌套或属性变化导致匹配失败或安全漏洞。
动作: 读取全部内容为字符串,使用 preg_match_all 匹配。

$xml = "";
$f = fopen( 'test.xml', 'r' );
while( $data = fread( $f, 4096 ) ) { $xml .= $data; }
fclose( $f );

preg_match_all( "/\<book\>(.*?)\<\/book\>/s", $xml, $bookblocks );
foreach( $bookblocks[1] as $block ){
    preg_match_all( "/\<author\>(.*?)\<\/author\>/", $block, $author );
    preg_match_all( "/\<title\>(.*?)\<\/title\>/", $block, $title );
    preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/", $block, $publisher );
    echo( $title[1][0]." - ". $author[1][0]." - ". $publisher[1][0]."\n" );
}

第4步:使用 DOM 编写(生成)XML

目的: 在内存中构建符合标准的 XML 结构,避免手动拼接字符串导致的格式错误。
入口: 数组存储数据,实例化 DOMDocument。
动作: 创建根节点,循环创建子节点及文本节点,依次添加到父节点下。
完成状态: 调用 saveXML() 即可获得格式化字符串。

$books = array(
    array('title' => 'PHP Hacks', 'author' => 'Jack Herrington', 'publisher' => "O'Reilly"),
    array('title' => 'Podcasting Hacks', 'author' => 'Jack Herrington', 'publisher' => "O'Reilly")
);

$doc = new DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "books" );
$doc->appendChild( $r );

foreach( $books as $book ){
    $b = $doc->createElement( "book" );
    
    $author = $doc->createElement( "author" );
    $author->appendChild( $doc->createTextNode( $book['author'] ) );
    $b->appendChild( $author );
    
    $title = $doc->createElement( "title" );
    $title->appendChild( $doc->createTextNode( $book['title'] ) );
    $b->appendChild( $title );
    
    $publisher = $doc->createElement( "publisher" );
    $publisher->appendChild( $doc->createTextNode( $book['publisher'] ) );
    $b->appendChild( $publisher );
    
    $r->appendChild( $b );
}
// echo $doc->saveXML();

第5步:PHP 混合模式写入 XML

目的: 类似于 PHP 输出 HTML,直接在 XML 结构中嵌入 PHP 逻辑代码,适合静态结构较多、动态数据较少的简单场景。
注意: 这并非标准的数据处理方式,而是一种视图层的技巧。

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

简要总结

对于结构化且可能发生变更的 XML,DOMDocument 是最稳妥的选择;处理超大文件时应优先考虑基于事件的 SAX 解析;正则表达式应尽量避免用于复杂的 XML 解析工作。以上即为使用PHP实现读取和编写XML DOM代码的详细内容,更多关于PHP XML教程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表