PHP Conference Japan 2024

XMLReader 類別

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

簡介

XMLReader 擴充套件是一個 XML 拉式解析器 (XML Pull Parser)。 讀取器就像一個游標,在文件串流上向前移動,並在途中的每個節點處停止。

類別概要

class XMLReader {
/* 常數 */
public const int NONE;
public const int ELEMENT;
public const int ATTRIBUTE;
公開 常數 整數 TEXT;
公開 常數 整數 CDATA;
公開 常數 整數 ENTITY_REF;
公開 常數 整數 ENTITY;
公開 常數 整數 PI;
公開 常數 整數 COMMENT;
公開 常數 整數 DOC;
公開 常數 整數 DOC_TYPE;
公開 常數 整數 DOC_FRAGMENT;
公開 常數 整數 NOTATION;
公開 常數 整數 WHITESPACE;
公開 常數 整數 END_ELEMENT;
公開 常數 整數 END_ENTITY;
公開 常數 整數 XML_DECLARATION;
公開 常數 整數 LOADDTD;
公開 常數 整數 DEFAULTATTRS;
公開 常數 整數 VALIDATE;
公開 常數 整數 SUBST_ENTITIES;
/* 屬性 */
公開 整數 $depth;
公開 字串 $name;
公開 字串 $prefix;
公開 字串 $value;
/* 方法 */
公開 close():
公開 expand(?DOMNode $baseNode = null): DOMNode|
公開 靜態 fromStream(
    資源 $stream,
    ?字串 $encoding = null,
    整數 $flags = 0,
    ?字串 $documentUri = null
): static
public static 從字串建立(字串 $source, ?字串 $encoding = null, 整數 $flags = 0): static
public static 從 URI 建立(字串 $uri, ?字串 $encoding = null, 整數 $flags = 0): static
public 取得屬性(字串 $name): ?字串
公開 moveToAttributeNo(int $index): bool
公開 moveToAttributeNs(string $name, string $namespace): bool
公開 next(?string $name = null): bool
公開 靜態 open(string $uri, ?string $encoding = null, int $flags = 0): XMLReader
公開 open(string $uri, ?string $encoding = null, int $flags = 0): bool
公開 read(): bool
公開 readString(): string
公開 setParserProperty(整數 $property, 布林 $value): 布林
公開 setRelaxNGSchema(?字串 $filename): 布林
公開 setSchema(?字串 $filename): 布林
公開 靜態 XML(字串 $source, ?字串 $encoding = null, 整數 $flags = 0): XMLReader
公開 XML(字串 $source, ?字串 $encoding = null, 整數 $flags = 0): 布林
}

屬性

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 作為輸出(例如《戰地風雲:英雄》生成的聯合供稿 URL)。使用 get_file_contents(url),您可以從這些 URL 檢索 XML 數據,並將其作為變量傳遞以作為 XML 字串進行處理。

遺憾的是,SimpleXML 或 XML DOM 無法處理所有 XML 字串。有些在末尾添加了錯誤框(例如《戰地風雲:英雄》的聯合新聞)。這些框會導致文件結尾類型的錯誤並關閉腳本。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 年前
用於簡單 SAX 讀取大型 XML 的 XMLReader 包裝類別
https://github.com/dkrnl/SimpleXMLReader

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

<?php

/**
* Simple XML Reader
*
* @license Public Domain
* @author Dmitry Pyatkov(aka dkrnl) <dkrnl@yandex.ru>
* @url http://github.com/dkrnl/SimpleXMLReader
*/
class SimpleXMLReader extends XMLReader
{

/**
* Callbacks
*
* @var array
*/
protected $callback = array();

/**
* Add node callback
*
* @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("Already exists callback $name($nodeType).");
}
if (!
is_callable($callback)) {
throw new
Exception("Already exists parser callback $name($nodeType).");
}
$this->callback[$nodeType][$name] = $callback;
return
$this;
}

/**
* Remove node callback
*
* @param string $name
* @param integer $nodeType
* @return SimpleXMLReader
*/
public function unRegisterCallback($name, $nodeType = XMLREADER::ELEMENT)
{
if (!isset(
$this->callback[$nodeType][$name])) {
throw new
Exception("Unknow parser callback $name($nodeType).");
}
unset(
$this->callback[$nodeType][$name]);
return
$this;
}

/**
* Run parser
*
* @return void
*/
public function parse()
{
if (empty(
$this->callback)) {
throw new
Exception("Empty parser callback.");
}
$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);
}
}
}

/**
* Run XPath query on current node
*
* @param string $path
* @param string $version
* @param string $encoding
* @return array(SimpleXMLElement)
*/
public function expandXpath($path, $version = "1.0", $encoding = "UTF-8")
{
return
$this->expandSimpleXml($version, $encoding)->xpath($path);
}

/**
* Expand current node to string
*
* @param string $version
* @param string $encoding
* @return SimpleXMLElement
*/
public function expandString($version = "1.0", $encoding = "UTF-8")
{
return
$this->expandSimpleXml($version, $encoding)->asXML();
}

/**
* Expand current node to SimpleXMLElement
*
* @param string $version
* @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);
}

/**
* Expand current node to DomDocument
*
* @param string $version
* @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;
}

}
?>
desk_ocean at msn dot com
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 含有空元素
godseth at o2 dot pl
16 年前
感謝 rein_baarsma33 AT hotmail DOT com 修正錯誤。

這是基於我和你們的修改後,新的 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);
}
}
}
}

}

?>

【danbrown AT php DOT net 編輯:此頁面上的使用者註記(現已移除)中,「Alex」和 (qdog AT qview DOT org) 也提供了修正。】
japos dot trash at googlemail dot com
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
函式 parseXML($node,$seq,$path) {
全域變數
$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
' [具有屬性: ';
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 [具有屬性: @id = 4 @name = foo ]
2-3 /tag1/text() = is
1-4 /text() = a
1-5 /tag2 [具有屬性: @id = 5 ]
2-6 /text() = common
1-7 /text() = record
eef dot vreeland at gmail dot com
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

... 並且在測試屬性時務必使用 '===' 運算子。
eef dot vreeland at gmail dot com
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
casella dot email at google dot mail dot com
12 年前
要驗證所有節點讀取時沒有錯誤/警告,您可以使用以下程式碼:
<?php
$endofxml
= false;
$xml_url = "example.xml";
$reader = new XMLReader();
if(!
$reader->open($xml_url)){
print
"開啟 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
"沒有發現錯誤";
} else {
print
"發現錯誤";
}
?>

這段程式碼可用於捕捉 $reader->read() 的錯誤/警告。
boukeversteegh at gmail dot com
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 節點作為第一個子節點,而不是僅返回根節點。
andrei_antal at yahoo dot com
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
"$customername\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
函數 xml2assoc($xml) {
$arr = 陣列();
如果 (!
preg_match_all('|\<\s*?(\w+).*?\>(.*)\<\/\s*\\1.*?\>|s', $xml, $m)) 傳回 $xml;
如果 (
is_array($m[1]))
對於 (
$i = 0;$i < sizeof($m[1]); $i++) $arr[$m[1][$i]] = xml2assoc($m[2][$i]);
否則
$arr[$m[1]] = xml2assoc($m[2]);

傳回
$arr;
}
?>
To Top