2024 年 PHP 日本大会

XMLReader 类

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

介绍

XMLReader 扩展是一个 XML 拉取解析器。读取器充当游标,向前移动文档流,并在途中停留在每个节点。

类概要

class XMLReader {
/* 常量 */
public const int NONE;
public const int ELEMENT;
public const int ATTRIBUTE;
public const int TEXT;
public const int CDATA;
public const int ENTITY_REF;
public const int ENTITY;
public const int PI;
public const int COMMENT;
public const int DOC;
public const int DOC_TYPE;
public const int DOC_FRAGMENT;
public const int NOTATION;
public const int WHITESPACE;
public const int END_ELEMENT;
public const int END_ENTITY;
public const int XML_DECLARATION;
public const int LOADDTD;
public const int DEFAULTATTRS;
public const int VALIDATE;
public const int SUBST_ENTITIES;
/* 属性 */
public int $depth;
public bool $hasValue;
public string $name;
public int $nodeType;
public string $prefix;
public string $value;
/* 方法 */
public close(): true
public expand(?DOMNode $baseNode = null): DOMNode|false
public static fromStream(
    resource $stream,
    ?string $encoding = null,
    int $flags = 0,
    ?string $documentUri = null
): static
public static fromString(string $source, ?string $encoding = null, int $flags = 0): static
public static fromUri(string $uri, ?string $encoding = null, int $flags = 0): static
public getAttribute(string $name): ?string
public getAttributeNo(int $index): ?string
public getAttributeNs(string $name, string $namespace): ?string
public getParserProperty(int $property): bool
public isValid(): bool
public lookupNamespace(string $prefix): ?string
public moveToAttribute(string $name): bool
public moveToAttributeNo(int $index): bool
public moveToAttributeNs(string $name, string $namespace): bool
public next(?string $name = null): bool
public static open(string $uri, ?string $encoding = null, int $flags = 0): XMLReader
public open(string $uri, ?string $encoding = null, int $flags = 0): bool
public read(): bool
public readString(): string
public setParserProperty(int $property, bool $value): bool
public setRelaxNGSchema(?string $filename): bool
public setSchema(?string $filename): bool
public static XML(string $source, ?string $encoding = null, int $flags = 0): XMLReader
public XML(string $source, ?string $encoding = null, int $flags = 0): bool
}

属性

attributeCount

节点上的属性数量

baseURI

节点的基准 URI

depth

节点在树中的深度,从 0 开始

hasAttributes

指示节点是否具有属性

hasValue

指示节点是否具有文本值

isDefault

指示属性是否为 DTD 中的默认值

isEmptyElement

指示节点是否是空元素标签

localName

节点的局部名称

name

节点的限定名称

namespaceURI

与节点关联的命名空间的 URI

nodeType

节点的节点类型

prefix

与节点关联的命名空间的前缀

value

节点的文本值

xmlLang

节点所在的 xml:lang 作用域

预定义常量

XMLReader 节点类型

XMLReader::NONE

无节点类型

XMLReader::ELEMENT

开始元素

XMLReader::ATTRIBUTE

属性节点

XMLReader::TEXT

文本节点

XMLReader::CDATA

CDATA 节点

XMLReader::ENTITY_REF

实体引用节点

XMLReader::ENTITY

实体声明节点

XMLReader::PI

处理指令节点

XMLReader::COMMENT

注释节点

XMLReader::DOC

文档节点

XMLReader::DOC_TYPE

文档类型节点

XMLReader::DOC_FRAGMENT

文档片段节点

XMLReader::NOTATION

符号节点

XMLReader::WHITESPACE

空白节点

XMLReader::SIGNIFICANT_WHITESPACE

有效空白节点

XMLReader::END_ELEMENT

结束元素

XMLReader::END_ENTITY

结束实体

XMLReader::XML_DECLARATION

XML 声明节点

XMLReader 解析器选项

XMLReader::LOADDTD

加载 DTD 但不验证

XMLReader::DEFAULTATTRS

加载 DTD 和默认属性,但不验证

XMLReader::VALIDATE

加载DTD并在解析时进行验证

XMLReader::SUBST_ENTITIES

替换实体并展开引用

变更日志

版本 描述
8.4.0 类常量现在已进行类型声明。

目录

添加注释

用户贡献的注释 17 条注释

james dot ellis at example dot com
15年前
此处提到的“XML2Assoc”函数应谨慎使用……基本上,它们正在复制SimpleXML中已存在的函数。它们可能有效,但无法扩展。

解析XML主要有两个用例,每个用例都适合XMLReader或SimpleXML。

1. SimpleXML是使用原生PHP数据类型轻松访问XML文档树的优秀工具。当处理大型(约> 50M)XML文档时,它开始变得笨拙,因为它会在处理之前将整个文档读取到内存中。当您的服务器内存不足时(或者会导致负载峰值),SimpleXML只会嘲笑您然后崩溃。

2. 除了处理大型XML文档的原因外,如果您必须处理大型XML文档,请使用XMLReader来处理它们。不要尝试使用XMLReader和PHP xml2assoc()函数将整个XML文档收集到PHP数据结构中,您是在重新发明SimpleXML的轮子。
使用XMLReader解析大型XML文档时,收集执行操作所需的数据,然后在跳到下一个节点之前执行该操作。不要从大型XML文档构建大型数据结构,您的服务器(及其管理员)不会喜欢您。
lee8oi at gmail dot com
12年前
有时您有一个不寻常的URL,它实际上并不指向xml文件,但仍然返回xml作为输出(例如Battlefield Heroes生成的syndication urls)。使用get_file_contents(url),您可以从这些url检索xml数据并将其作为变量传递以将其作为XML字符串进行处理。

不幸的是,simpleXML或xml DOM无法处理所有xml字符串。有些在末尾添加了错误框(例如Battlefield Heroes联合新闻)。这些框会导致文件结尾错误并关闭脚本。XMLReader可以无错误地从这些字符串中获取数据。
jart (at) mail.ru
14年前
大家好,我希望这个例子能帮到你们
您可以删除显示过程的打印信息 —
它将成为一段不错的代码。

<?php
function xml2assoc($xml, $name)
{
print
"<ul>";

$tree = null;
print(
"I'm inside " . $name . "<br>");

while(
$xml->read())
{
if(
$xml->nodeType == XMLReader::END_ELEMENT)
{
print
"</ul>";
return
$tree;
}

else if(
$xml->nodeType == XMLReader::ELEMENT)
{
$node = array();

print(
"Adding " . $xml->name ."<br>");
$node['tag'] = $xml->name;

if(
$xml->hasAttributes)
{
$attributes = array();
while(
$xml->moveToNextAttribute())
{
print(
"Adding attr " . $xml->name ." = " . $xml->value . "<br>");
$attributes[$xml->name] = $xml->value;
}
$node['attr'] = $attributes;
}

if(!
$xml->isEmptyElement)
{
$childs = xml2assoc($xml, $node['tag']);
$node['childs'] = $childs;
}

print(
$node['tag'] . " added <br>");
$tree[] = $node;
}

else if(
$xml->nodeType == XMLReader::TEXT)
{
$node = array();
$node['text'] = $xml->value;
$tree[] = $node;
print
"text added = " . $node['text'] . "<br>";
}
}

print
"returning " . count($tree) . " childs<br>";
print
"</ul>";

return
$tree;
}

echo
"<PRE>";

$xml = new XMLReader();
$xml->open('test.xml');
$assoc = xml2assoc($xml, "root");
$xml->close();

print_r($assoc);
echo
"</PRE>";

?>

它读取此xml

<test>
<hallo volume="loud"> me <br/> lala </hallo>
<hallo> me </hallo>
</test>
kula_shakerz
11年前
在msdn的IXmlReader文档中发现了这一点,但这对于PHP中的XMLReader也是有效的。

您应该在处理属性之前保存$isEmptyElement的值,或者调用moveToElement使$isEmptyElement在处理属性后有效。

当XMLReader定位在属性节点上时,即使属性的父元素为空,$isEmptyElement也会返回FALSE。
Sean Colin Ruiz
7年前
正如japos提到的那样。注意您如何使用isEmptyElement。完成属性循环后:isEmptyElement将为false。您可以使用moveToElement()将光标移回元素,然后您可以像往常一样再次使用isEmptyElement。
dkrnl at yandex dot ru
11年前
XMLReader包装类,用于简单地SAX读取大型xml
https://github.com/dkrnl/SimpleXMLReader

用法示例:http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php

<?php

/**
* 简易 XML 读取器
*
* @license 公共领域
* @author Dmitry Pyatkov(aka dkrnl) <[email protected]>
* @url http://github.com/dkrnl/SimpleXMLReader
*/
class SimpleXMLReader extends XMLReader
{

/**
* 回调函数
*
* @var array
*/
protected $callback = array();

/**
* 添加节点回调函数
*
* @param string $name 节点名称
* @param callback $callback 回调函数
* @param integer $nodeType 节点类型
* @return SimpleXMLReader
*/
public function registerCallback($name, $callback, $nodeType = XMLREADER::ELEMENT)
{
if (isset(
$this->callback[$nodeType][$name])) {
throw new
Exception("回调函数 $name($nodeType) 已存在.");
}
if (!
is_callable($callback)) {
throw new
Exception("解析器回调函数 $name($nodeType) 已存在.");
}
$this->callback[$nodeType][$name] = $callback;
return
$this;
}

/**
* 删除节点回调函数
*
* @param string $name 节点名称
* @param integer $nodeType 节点类型
* @return SimpleXMLReader
*/
public function unRegisterCallback($name, $nodeType = XMLREADER::ELEMENT)
{
if (!isset(
$this->callback[$nodeType][$name])) {
throw new
Exception("未知的解析器回调函数 $name($nodeType).");
}
unset(
$this->callback[$nodeType][$name]);
return
$this;
}

/**
* 运行解析器
*
* @return void
*/
public function parse()
{
if (empty(
$this->callback)) {
throw new
Exception("解析器回调函数为空.");
}
$continue = true;
while (
$continue && $this->read()) {
if (isset(
$this->callback[$this->nodeType][$this->name])) {
$continue = call_user_func($this->callback[$this->nodeType][$this->name], $this);
}
}
}

/**
* 在当前节点上运行 XPath 查询
*
* @param string $path XPath 表达式
* @param string $version XML 版本
* @param string $encoding 编码
* @return array(SimpleXMLElement)
*/
public function expandXpath($path, $version = "1.0", $encoding = "UTF-8")
{
return
$this->expandSimpleXml($version, $encoding)->xpath($path);
}

/**
* 将当前节点扩展为字符串
*
* @param string $version XML 版本
* @param string $encoding 编码
* @return SimpleXMLElement
*/
public function expandString($version = "1.0", $encoding = "UTF-8")
{
return
$this->expandSimpleXml($version, $encoding)->asXML();
}

/**
* 将当前节点扩展为 SimpleXMLElement
*
* @param string $version XML 版本
* @param string $encoding 编码
* @param string $className 类名
* @return SimpleXMLElement
*/
public function expandSimpleXml($version = "1.0", $encoding = "UTF-8", $className = null)
{
$element = $this->expand();
$document = new DomDocument($version, $encoding);
$node = $document->importNode($element, true);
$document->appendChild($node);
return
simplexml_import_dom($node, $className);
}

/**
* 将当前节点扩展为 DomDocument
*
* @param string $version XML 版本
* @param string $encoding 编码
* @return DomDocument
*/
public function expandDomDocument($version = "1.0", $encoding = "UTF-8")
{
$element = $this->expand();
$document = new DomDocument($version, $encoding);
$node = $document->importNode($element, true);
$document->appendChild($node);
return
$document;
}

}
?>
[email protected]
16 年前
根据 Sergey Aikinkulov 的注释进行了一些修改

<?php
function xml2assoc(&$xml){
$assoc = NULL;
$n = 0;
while(
$xml->read()){
if(
$xml->nodeType == XMLReader::END_ELEMENT) break;
if(
$xml->nodeType == XMLReader::ELEMENT and !$xml->isEmptyElement){
$assoc[$n]['name'] = $xml->name;
if(
$xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
$assoc[$n]['val'] = xml2assoc($xml);
$n++;
}
else if(
$xml->isEmptyElement){
$assoc[$n]['name'] = $xml->name;
if(
$xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
$assoc[$n]['val'] = "";
$n++;
}
else if(
$xml->nodeType == XMLReader::TEXT) $assoc = $xml->value;
}
return
$assoc;
}
?>

添加了 else if($xml->isEmptyElement)
一些 XML 可能包含空元素
[email protected]
16 年前
感谢 [email protected] 提供的bug修复。

这是我基于我和你修改的XML解析方法的新版本。

XML2ASSOC 是一个解析普通XML的完整解决方案。

<?php
/**
* XML2Assoc Class to creating
* PHP Assoc Array from XML File
*
* @author godseth (AT) o2.pl & rein_baarsma33 (AT) hotmail.com (Bugfixes in parseXml Method)
* @uses XMLReader
*
*/

class Xml2Assoc {

/**
* Optimization Enabled / Disabled
*
* @var bool
*/
protected $bOptimize = false;

/**
* Method for loading XML Data from String
*
* @param string $sXml
* @param bool $bOptimize
*/

public function parseString( $sXml , $bOptimize = false) {
$oXml = new XMLReader();
$this -> bOptimize = (bool) $bOptimize;
try {

// Set String Containing XML data
$oXml->XML($sXml);

// Parse Xml and return result
return $this->parseXml($oXml);

} catch (
Exception $e) {
echo
$e->getMessage();
}
}

/**
* Method for loading Xml Data from file
*
* @param string $sXmlFilePath
* @param bool $bOptimize
*/
public function parseFile( $sXmlFilePath , $bOptimize = false ) {
$oXml = new XMLReader();
$this -> bOptimize = (bool) $bOptimize;
try {
// Open XML file
$oXml->open($sXmlFilePath);

// // Parse Xml and return result
return $this->parseXml($oXml);

} catch (
Exception $e) {
echo
$e->getMessage(). ' | Try open file: '.$sXmlFilePath;
}
}

/**
* XML Parser
*
* @param XMLReader $oXml
* @return array
*/
protected function parseXml( XMLReader $oXml ) {

$aAssocXML = null;
$iDc = -1;

while(
$oXml->read()){
switch (
$oXml->nodeType) {

case
XMLReader::END_ELEMENT:

if (
$this->bOptimize) {
$this->optXml($aAssocXML);
}
return
$aAssocXML;

case
XMLReader::ELEMENT:

if(!isset(
$aAssocXML[$oXml->name])) {
if(
$oXml->hasAttributes) {
$aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
} else {
if(
$oXml->isEmptyElement) {
$aAssocXML[$oXml->name] = '';
} else {
$aAssocXML[$oXml->name] = $this->parseXML($oXml);
}
}
} elseif (
is_array($aAssocXML[$oXml->name])) {
if (!isset(
$aAssocXML[$oXml->name][0]))
{
$temp = $aAssocXML[$oXml->name];
foreach (
$temp as $sKey=>$sValue)
unset(
$aAssocXML[$oXml->name][$sKey]);
$aAssocXML[$oXml->name][] = $temp;
}

if(
$oXml->hasAttributes) {
$aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
} else {
if(
$oXml->isEmptyElement) {
$aAssocXML[$oXml->name][] = '';
} else {
$aAssocXML[$oXml->name][] = $this->parseXML($oXml);
}
}
} else {
$mOldVar = $aAssocXML[$oXml->name];
$aAssocXML[$oXml->name] = array($mOldVar);
if(
$oXml->hasAttributes) {
$aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
} else {
if(
$oXml->isEmptyElement) {
$aAssocXML[$oXml->name][] = '';
} else {
$aAssocXML[$oXml->name][] = $this->parseXML($oXml);
}
}
}

if(
$oXml->hasAttributes) {
$mElement =& $aAssocXML[$oXml->name][count($aAssocXML[$oXml->name]) - 1];
while(
$oXml->moveToNextAttribute()) {
$mElement[$oXml->name] = $oXml->value;
}
}
break;
case
XMLReader::TEXT:
case
XMLReader::CDATA:

$aAssocXML[++$iDc] = $oXml->value;

}
}

return
$aAssocXML;
}

/**
* Method to optimize assoc tree.
* ( Deleting 0 index when element
* have one attribute / value )
*
* @param array $mData
*/
public function optXml(&$mData) {
if (
is_array($mData)) {
if (isset(
$mData[0]) && count($mData) == 1 ) {
$mData = $mData[0];
if (
is_array($mData)) {
foreach (
$mData as &$aSub) {
$this->optXml($aSub);
}
}
} else {
foreach (
$mData as &$aSub) {
$this->optXml($aSub);
}
}
}
}

}

?>

[[email protected] 编辑:修复程序也由“Alex”和([email protected]) 在此页面的用户留言中提供(现已删除)。]
[email protected]
14年前
注意 XMLReader::$isElementEmpty 的使用方法。我不知道这是不是一个bug,但是 $isElementEmpty 是针对当前上下文设置的,而不仅仅是针对元素。如果你将光标移动到一个属性上,$isElementEmpty 将始终为false。

<?php
$xml
= new XMLReader();
$xml->XML('<tag attr="value" />');
$xml->read();
var_dump($xml->isEmptyElement);
$xml->moveToNextAttribute();
var_dump($xml->isEmptyElement);
?>

输出结果为

(bool) true
(bool) false

所以,确保在移动光标之前存储 $isEmptyElement。
itari
16 年前
<?php
function parseXML($node,$seq,$path) {
global
$oldpath;
if (!
$node->read())
return;
if (
$node->nodeType != 15) {
print
'<br/>'.$node->depth;
print
'-'.$seq++;
print
' '.$path.'/'.($node->nodeType==3?'text() = ':$node->name);
print
$node->value;
if (
$node->hasAttributes) {
print
' [hasAttributes: ';
while (
$node->moveToNextAttribute()) print '@'.$node->name.' = '.$node->value.' ';
print
']';
}
if (
$node->nodeType == 1) {
$oldpath=$path;
$path.='/'.$node->name;
}
parseXML($node,$seq,$path);
}
else
parseXML($node,$seq,$oldpath);
}

$source = "<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>";
$xml = new XMLReader();
$xml->XML($source);
print
htmlspecialchars($source).'<br/>';
parseXML($xml,0,'');
?>

输出

<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>

0-0 /tag1
1-1 /tag1/text() = this
1-2 /tag1/tag2 [hasAttributes: @id = 4 @name = foo ]
2-3 /tag1/text() = is
1-4 /text() = a
1-5 /tag2 [hasAttributes: @id = 5 ]
2-6 /text() = common
1-7 /text() = record
[email protected]
7年前
请忽略我之前的留言;我点击“添加留言”太快了。

关于(非)自闭合标签

A) <tag></tag>
$xmlRdr->isEmptyElement => false
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => false

B) <tag />
$xmlRdr->isEmptyElement => true
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => false

C) <tag attribute="value"></tag>
$xmlRdr->isEmptyElement => false
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => true

D) <tag attribute="value" />
$xmlRdr->isEmptyElement => true
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => true

...并且在测试属性时始终使用'==='运算符。
[email protected]
7年前
注意,当

A) <tag></tag>
$xmlRdr->isEmptyElement => false
$xmlRdr->hasValue => true
$xmlRdr->value => ''
$xmlRdr->hasAttributes => false

B) <tag />
$xmlRdr->isEmptyElement => true
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => false

C) <tag attribute="value"></tag>
$xmlRdr->isEmptyElement => false
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => true

D) <tag attribute="value" />
$xmlRdr->isEmptyElement => true
$xmlRdr->hasValue => false
$xmlRdr->value => ''
$xmlRdr->hasAttributes => true
[email protected]
12年前
要验证所有节点均无错误/警告地读取,可以使用以下代码
<?php
$endofxml
= false;
$xml_url = "example.xml";
$reader = new XMLReader();
if(!
$reader->open($xml_url)){
print
"Error to open XML: $xml_url\n";
} else {
while (
$reader->read()) {
$firstnode = (!isset($firstnode)) ? $reader->name : $firstnode;
/*
执行某些操作
*/
if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == $firstnode) {
$endofxml = true;
}
}
}
if(
$endofxml) {
print
"no error found";
} else {
print
"error found";
}
?>

此代码用于捕获 $reader->read() 错误/警告。
[email protected]
15年前
XML 到关联数组

基于Sergey Aikinkulov改进的算法。问题是,如果节点具有相同的标签名称,它会覆盖节点。因此<a><b/><b/><a>将被读取为<a><b/><a/>。此算法更好地处理此问题,并输出易于理解的数组。

<?php
function xml2assoc($xml) {
$tree = null;
while(
$xml->read())
switch (
$xml->nodeType) {
case
XMLReader::END_ELEMENT: return $tree;
case
XMLReader::ELEMENT:
$node = array('tag' => $xml->name, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
if(
$xml->hasAttributes)
while(
$xml->moveToNextAttribute())
$node['attributes'][$xml->name] = $xml->value;
$tree[] = $node;
break;
case
XMLReader::TEXT:
case
XMLReader::CDATA:
$tree .= $xml->value;
}
return
$tree;
}

?>

使用方法

myxml.xml
------
<PERSON>
<NAME>John</NAME>
<PHONE type="home">555-555-555</PHONE>
</PERSON>
----

<?
$xml = new XMLReader();
$xml->open('myxml.xml');
$assoc = xml2assoc($xml);
$xml->close();
print_r($assoc);
?>

输出结果
数组
(
[0] => 数组
(
[tag] => PERSON
[value] => 数组
(
[0] => 数组
(
[tag] => NAME
[value] => John
)

[1] => 数组
(
[tag] => PHONE
[value] => 555-555-555
[attributes] => 数组
(
[type] => home
)

)

)

)

)

由于递归的原因,它返回一个数组,其中根XML节点作为第一个子节点,而不是只返回根节点。
[email protected]
15年前
<?php
//提取特定元素
$reader = new XMLReader();
$reader->open($xmlfile);
while (
$reader->read()) {
switch (
$reader->nodeType) {
case (
XMLREADER::ELEMENT):

if (
$reader->name == "Code")
{
$reader->read();
$code = trim($reader->value);
echo
"$code\n";
break;
}

if (
$reader->name == "Name")
{
$reader->read();
$customername = trim( $reader->value );
echo
"$name\n";
break;
}

if (
$reader->name == "Camp")
{
$camp = trim($reader->getAttribute("ID"));
echo
"$camp\n";
break;
}
}
}
?>
Sergey Aikinkulov
16 年前
下一版本xml2assoc将包含一些改进和修复
- 无重复数据
- 无缓冲数组

<?php
/*
将XML结构读取到关联数组
--
使用方法:
$xml = new XMLReader();
$xml->open([XML文件]);
$assoc = xml2assoc($xml);
$xml->close();
*/
function xml2assoc($xml) {
$assoc = null;
while(
$xml->read()){
switch (
$xml->nodeType) {
case
XMLReader::END_ELEMENT: return $assoc;
case
XMLReader::ELEMENT:
$assoc[$xml->name][] = array('value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
if(
$xml->hasAttributes){
$el =& $assoc[$xml->name][count($assoc[$xml->name]) - 1];
while(
$xml->moveToNextAttribute()) $el['attributes'][$xml->name] = $xml->value;
}
break;
case
XMLReader::TEXT:
case
XMLReader::CDATA: $assoc .= $xml->value;
}
}
return
$assoc;
}
?>
PxL
15年前
一个基本的解析器

<?php
function xml2assoc($xml) {
$arr = array();
if (!
preg_match_all('|\<\s*?(\w+).*?\>(.*)\<\/\s*\\1.*?\>|s', $xml, $m)) return $xml;
if (
is_array($m[1]))
for (
$i = 0;$i < sizeof($m[1]); $i++) $arr[$m[1][$i]] = xml2assoc($m[2][$i]);
else
$arr[$m[1]] = xml2assoc($m[2]);

return
$arr;
}
?>
To Top