首页 php教程 php手册 使用PHP 5.0 轻松解析XML文档

使用PHP 5.0 轻松解析XML文档

Jun 21, 2016 am 09:00 AM
attributes function name this xml

用sax方式的时候,要自己构建3个函数,而且要直接用这三的函数来返回数据, 要求较强的逻辑。 在处理不同结构的XML的时候, 还要重新进行构造这三个函数,麻烦!

用dom方式,倒是好些,但是他把每个节点都看作是一个node,操作起来要写好多的代码, 麻烦!

网上有好多的开源的xml解析的类库, 以前看过几个,但是心里总是觉得不踏实,感觉总是跟在别人的屁股后面.

这几天在搞Java, 挺累的,所以决定换换脑袋,写点PHP代码,为了防止以后xml解析过程再令我犯难,就花了一天的时间写了下面一个xml解析的类,于是就有了下面的东西。

实现方式是通过包装"sax方式的解析结果"来实现的. 总的来说,对于我个人来说挺实用的,性能也还可以,基本上可以完成大多数的处理要求。

功能:

1、 对基本的xml文件的节点进行 查询 / 添加 / 修改 / 删除 工作.

2、导出xml文件的所有数据到一个数组里面.

3、整个设计采用了oo方式,在操作结果集的时候, 使用方法类似于dom

缺点:

1、 每个节点最好都带有一个id(看后面的例子), 每个“节点名字”=“节点的标签_节点的id”,如果这个id值没有设置,程序将自动给他产生一个id,这个id就是这个节点在他的上级节点中的位置编号,从0开始。

2、 查询某个节点的时候可以通过用“|”符号连接“节点名字”来进行。这些“节点名字”都是按顺序写好的上级节点的名字。

使用说明:

运行下面的例子,在执行结果页面上可以看到函数的使用说明

代码是通过php5来实现的,在php4中无法正常运行。

由于刚刚写完,所以没有整理文档,下面的例子演示的只是一部分的功能,代码不是很难,要是想知道更多的功能,可以研究研究源代码。

目录结构:

test.php

test.xml

xml / SimpleDocumentBase.php

xml / SimpleDocumentNode.php

xml / SimpleDocumentRoot.php

xml / SimpleDocumentParser.php

文件:test.xml

<?xml version="1.0" encoding="GB2312"?><shop> <name>华联</name> <address>北京长安街-9999号</address> <desc>连锁超市</desc> <cat id="food"> <goods id="food11"> <name>food11</name> <price>12.90</price> </goods> <goods id="food12"> <name>food12</name> <price>22.10</price> <desc creator="hahawen">好东西推荐</desc> </goods> </cat> <cat> <goods id="tel21"> <name>tel21</name> <price>1290</price> </goods> </cat> <cat id="coat"> <goods id="coat31"> <name>coat31</name> <price>112</price> </goods> <goods id="coat32"> <name>coat32</name> <price>45</price> </goods> </cat> <special id="hot"> <goods> <name>hot41</name> <price>99</price> </goods> </special></shop>

文件:test.php

<?php

require_once "xml/SimpleDocumentParser.php"; require_once "xml/SimpleDocumentBase.php"; require_once "xml/SimpleDocumentRoot.php"; require_once "xml/SimpleDocumentNode.php"; $test = new SimpleDocumentParser(); $test->parse("test.xml"); $dom = $test->getSimpleDocument(); echo "<pre>"; echo "<hr><font color=red>"; echo "下面是通过函数getSaveData()返回的整个xml数据的数组"; echo "</font><hr>"; print_r($dom->getSaveData()); echo "<hr><font color=red>"; echo "下面是通过setValue()函数,给给根节点添加信息,添加后显示出结果xml文件的内容"; echo "</font><hr>"; $dom->setValue("telphone", "123456789"); echo htmlspecialchars($dom->getSaveXml()); echo "<hr><font color=red>"; echo "下面是通过getNode()函数,返回某一个分类下的所有商品的信息"; echo "</font><hr>"; $obj = $dom->getNode("cat_food"); $nodeList = $obj->getNode(); foreach($nodeList as $node){ $data = $node->getValue(); echo "<font color=red>商品名:".$data[name]."</font><br>"; print_R($data); print_R($node->getAttribute()); } echo "<hr><font color=red>"; echo "下面是通过findNodeByPath()函数,返回某一商品的信息"; echo "</font><hr>"; $obj = $dom->findNodeByPath("cat_food|goods_food11"); if(!is_object($obj)){ echo "该商品不存在"; }else{ $data = $obj->getValue(); echo "<font color=red>商品名:".$data[name]."</font><br>"; print_R($data); print_R($obj->getAttribute()); } echo "<hr><font color=red>"; echo "下面是通过setValue()函数,给商品\"food11\"添加属性, 然后显示添加后的结果"; echo "</font><hr>"; $obj = $dom->findNodeByPath("cat_food|goods_food11"); $obj->setValue("leaveword", array("value"=>"这个商品不错", "attrs"=>array("author"=>"hahawen", "date"=>date('Y-m-d')))); echo htmlspecialchars($dom->getSaveXml()); echo "<hr><font color=red>"; echo "下面是通过removeValue()/removeAttribute()函数, 给商品\"food11\"改变和删除属性, 然后显示操作后的结果"; echo "</font><hr>"; $obj = $dom->findNodeByPath("cat_food|goods_food12"); $obj->setValue("name", "new food12"); $obj->removeValue("desc"); echo htmlspecialchars($dom->getSaveXml()); echo "<hr><font color=red>"; echo "下面是通过createNode()函数,添加商品, 然后显示添加后的结果"; echo "</font><hr>"; $obj = $dom->findNodeByPath("cat_food"); $newObj = $obj->createNode("goods", array("id"=>"food13")); $newObj->setValue("name", "food13"); $newObj->setValue("price", 100); echo htmlspecialchars($dom->getSaveXml()); echo "<hr><font color=red>"; echo "下面是通过removeNode()函数,删除商品, 然后显示删除后的结果"; echo "</font><hr>"; $obj = $dom->findNodeByPath("cat_food"); $obj->removeNode("goods_food12"); echo htmlspecialchars($dom->getSaveXml()); ?>

文件:SimpleDocumentParser.PHP

<?php

/**

*=========================================================

*

* @author hahawen(大龄青年)

* @since 2004-12-04

* @copyright Copyright (c) 2004, NxCoder Group

*

*=========================================================

*/

/**

* class SimpleDocumentParser

* use SAX parse XML file, and build SimpleDocumentObject

* all this pachage's is work for xml file, and method is action as DOM.

*

* @package SmartWeb.common.xml

* @version 1.0

*/

class SimpleDocumentParser

{

private $domRootObject = null;

private $currentNO = null;

private $currentName = null;

private $currentValue = null;

private $currentAttribute = null;

public function getSimpleDocument()

{

return $this->domRootObject;

}

public function parse($file)

{

$xmlParser = xml_parser_create();

xml_parser_set_option($xmlParser,XML_OPTION_CASE_FOLDING, 0);

xml_parser_set_option($xmlParser,XML_OPTION_SKIP_WHITE, 1);

xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, 'UTF-8');

xml_set_object($xmlParser, $this);

xml_set_element_handler($xmlParser, "startElement", "endElement");

xml_set_character_data_handler($xmlParser, "characterData");

if (!xml_parse($xmlParser, file_get_contents($file)))

die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlParser)),xml_get_current_line_number($xmlParser)));

xml_parser_free($xmlParser);

}

private function startElement($parser, $name, $attrs)

{

$this->currentName = $name;

$this->currentAttribute = $attrs;

if($this->currentNO == null)

{

$this->domRootObject = new SimpleDocumentRoot($name);

$this->currentNO = $this->domRootObject;

}

else

{

$this->currentNO = $this->currentNO->createNode($name, $attrs);

}

}

private function endElement($parser, $name)

{

if($this->currentName==$name)

{

$tag = $this->currentNO->getSeq();

$this->currentNO = $this->currentNO->getPNodeObject();

if($this->currentAttribute!=null && sizeof($this->currentAttribute)>0)

$this->currentNO->setValue($name, array('value'=>$this->currentValue, 'attrs'=>$this->currentAttribute));

else

$this->currentNO->setValue($name, $this->currentValue);

$this->currentNO->removeNode($tag);

}

else

{

$this->currentNO = (is_a($this->currentNO, 'SimpleDocumentRoot'))? null: $this->currentNO->getPNodeObject();

}

}

private function characterData($parser, $data)

{

$this->currentValue = iconv('UTF-8', 'GB2312', $data);

}

function __destruct()

{

unset($this->domRootObject);

}

}

?>

文件:SimpleDocumentBase.php

<?php

/**

*=========================================================

*

* @author hahawen(大龄青年)

* @since 2004-12-04

* @copyright Copyright (c) 2004, NxCoder Group

*

*=========================================================

*/

/**

* abstract class SimpleDocumentBase

* base class for xml file parse

* all this pachage's is work for xml file, and method is action as DOM.

*

* 1\ add/update/remove data of xml file.

* 2\ explode data to array.

* 3\ rebuild xml file

*

* @package SmartWeb.common.xml

* @abstract

* @version 1.0

*/

abstract class SimpleDocumentBase

{

private $nodeTag = null;

private $attributes = array();

private $values = array();

private $nodes = array();

function __construct($nodeTag)

{

$this->nodeTag = $nodeTag;

}

public function getNodeTag()

{

return $this->nodeTag;

}

public function setValues($values){

$this->values = $values;

}

public function setValue($name, $value)

{

$this->values[$name] = $value;

}

public function getValue($name=null)

{

return $name==null? $this->values: $this->values[$name];

}

public function removeValue($name)

{

unset($this->values["$name"]);

}

public function setAttributes($attributes){

$this->attributes = $attributes;

}

public function setAttribute($name, $value)

{

$this->attributes[$name] = $value;

}

public function getAttribute($name=null)

{

return $name==null? $this->attributes: $this->attributes[$name];

}

public function removeAttribute($name)

{

unset($this->attributes["$name"]);

}

public function getNodesSize()

{

return sizeof($this->nodes);

}

protected function setNode($name, $nodeId)

{

$this->nodes[$name] = $nodeId;

}

public abstract function createNode($name, $attributes);

public abstract function removeNode($name);

public abstract function getNode($name=null);

protected function getNodeId($name=null)

{

return $name==null? $this->nodes: $this->nodes[$name];

}

protected function createNodeByName($rootNodeObj, $name, $attributes, $pId)

{

$tmpObject = $rootNodeObj->createNodeObject($pId, $name, $attributes);

$key = isset($attributes[id])? $name.'_'.$attributes[id]: $name.'_'.$this->getNodesSize();

$this->setNode($key, $tmpObject->getSeq());

return $tmpObject;

}

protected function removeNodeByName($rootNodeObj, $name)

{

$rootNodeObj->removeNodeById($this->getNodeId($name));

if(sizeof($this->nodes)==1)

$this->nodes = array();

else

unset($this->nodes[$name]);

}

protected function getNodeByName($rootNodeObj, $name=null)

{

if($name==null)

{

$tmpList = array();

$tmpIds = $this->getNodeId();

foreach($tmpIds as $key=>$id)

$tmpList[$key] = $rootNodeObj->getNodeById($id);

return $tmpList;

}

else

{

$id = $this->getNodeId($name);

if($id===null)

{

$tmpIds = $this->getNodeId();

foreach($tmpIds as $tkey=>$tid)

{

if(strpos($key, $name)==0)

{

$id = $tid;

break;

}

}

}

return $rootNodeObj->getNodeById($id);

}

}

public function findNodeByPath($path)

{

$pos = strpos($path, '|');

if($pos<=0)

{

return $this->getNode($path);

}

else

{

$tmpObj = $this->getNode(substr($path, 0, $pos));

return is_object($tmpObj)? $tmpObj->findNodeByPath(substr($path, $pos+1)): null;

}

}

public function getSaveData()

{

$data = $this->values;

if(sizeof($this->attributes)>0)

$data[attrs] = $this->attributes;

$nodeList = $this->getNode();

if($nodeList==null)

return $data;

foreach($nodeList as $key=>$node)

{

$data[$key] = $node->getSaveData();

}

return $data;

}

public function getSaveXml($level=0)

{

$prefixSpace = str_pad("", $level, "\t");

$str = "$prefixSpace<$this->nodeTag";

foreach($this->attributes as $key=>$value)

$str .= " $key=\"$value\"";

$str .= ">\r\n";

foreach($this->values as $key=>$value){

if(is_array($value))

{

$str .= "$prefixSpace\t<$key";

foreach($value[attrs] as $attkey=>$attvalue)

$str .= " $attkey=\"$attvalue\"";

$tmpStr = $value[value];

}

else

{

$str .= "$prefixSpace\t<$key";

$tmpStr = $value;

}

$tmpStr = trim(trim($tmpStr, "\r\n"));

$str .= ($tmpStr===null || $tmpStr==="")? " />\r\n": ">$tmpStr</$key>\r\n";

}

foreach($this->getNode() as $node)

$str .= $node->getSaveXml($level+1)."\r\n";

$str .= "$prefixSpace</$this->nodeTag>";

return $str;

}

function __destruct()

{

unset($this->nodes, $this->attributes, $this->values);

}

}

?>

文件:SimpleDocumentRoot.PHP

<?php

/**

*=========================================================

*

* @author hahawen(大龄青年)

* @since 2004-12-04

* @copyright Copyright (c) 2004, NxCoder Group

*

*=========================================================

*/

/**

* class SimpleDocumentRoot

* XML root class, include values/attributes/subnodes.

* all this pachage's is work for xml file, and method is action as DOM.

*

* @package SmartWeb.common.xml

* @version 1.0

*/

class SimpleDocumentRoot extends SimpleDocumentBase

{

private $prefixStr = '<?xml version="1.0" encoding="utf-8" ?>';

private $nodeLists = array();

function __construct($nodeTag)

{

parent::__construct($nodeTag);

}

public function createNodeObject($pNodeId, $name, $attributes)

{

$seq = sizeof($this->nodeLists);

$tmpObject = new SimpleDocumentNode($this, $pNodeId, $name, $seq);

$tmpObject->setAttributes($attributes);

$this->nodeLists[$seq] = $tmpObject;

return $tmpObject;

}

public function removeNodeById($id)

{

if(sizeof($this->nodeLists)==1)

$this->nodeLists = array();

else

unset($this->nodeLists[$id]);

}

public function getNodeById($id)

{

return $this->nodeLists[$id];

}

public function createNode($name, $attributes)

{

return $this->createNodeByName($this, $name, $attributes, -1);

}

public function removeNode($name)

{

return $this->removeNodeByName($this, $name);

}

public function getNode($name=null)

{

return $this->getNodeByName($this, $name);

}

public function getSaveXml()

{

$prefixSpace = "";

$str = $this->prefixStr."\r\n";

return $str.parent::getSaveXml(0);

}

}

?>

文件:SimpleDocumentNode.php

<?php

/**

*=========================================================

*

* @author hahawen(大龄青年)

* @since 2004-12-04

* @copyright Copyright (c) 2004, NxCoder Group

*

*=========================================================

*/

/**

* class SimpleDocumentNode

* xml Node class, include values/attributes/subnodes.

* all this pachage's is work for xml file, and method is action as DOM.

*

* @package SmartWeb.common.xml

* @version 1.0

*/

class SimpleDocumentNode extends SimpleDocumentBase

{

private $seq = null;

private $rootObject = null;

private $pNodeId = null;

function __construct($rootObject, $pNodeId, $nodeTag, $seq)

{

parent::__construct($nodeTag);

$this->rootObject = $rootObject;

$this->pNodeId = $pNodeId;

$this->seq = $seq;

}

public function getPNodeObject()

{

return ($this->pNodeId==-1)? $this->rootObject: $this->rootObject->getNodeById($this->pNodeId);

}

public function getSeq(){

return $this->seq;

}

public function createNode($name, $attributes)

{

return $this->createNodeByName($this->rootObject, $name, $attributes, $this->getSeq());

}

public function removeNode($name)

{

return $this->removeNodeByName($this->rootObject, $name);

}

public function getNode($name=null)

{

return $this->getNodeByName($this->rootObject, $name);

}

}

?>

下面是例子运行对结果:

下面是通过函数getSaveData()返回的整个XML数据的数组

Array

(

[name] => 华联

[address] => 北京长安街-9999号

[desc] => 连锁超市

[cat_food] => Array

(

[attrs] => Array

(

[id] => food

)

[goods_food11] => Array

(

[name] => food11

[price] => 12.90

[attrs] => Array

(

[id] => food11

)

)

[goods_food12] => Array

(

[name] => food12

[price] => 22.10

[desc] => Array

(

[value] => 好东西推荐

[attrs] => Array

(

[creator] => hahawen

)

)

[attrs] => Array

(

[id] => food12

)

)

)

[cat_1] => Array

(

[goods_tel21] => Array

(

[name] => tel21

[price] => 1290

[attrs] => Array

(

[id] => tel21

)

)

)

[cat_coat] => Array

(

[attrs] => Array

(

[id] => coat

)

[goods_coat31] => Array

(

[name] => coat31

[price] => 112

[attrs] => Array

(

[id] => coat31

)

)

[goods_coat32] => Array

(

[name] => coat32

[price] => 45

[attrs] => Array

(

[id] => coat32

)

)

)

[special_hot] => Array

(

[attrs] => Array

(

[id] => hot

)

[goods_0] => Array

(

[name] => hot41

[price] => 99

)

)

)

下面是通过setValue()函数,给给根节点添加信息,添加后显示出结果xml文件的内容

<?xml version="1.0" encoding="GB2312" ?>

<shop>

<name>华联</name>

<address>北京长安街-9999号</address>

<desc>连锁超市</desc>

<telphone>123456789</telphone>

<cat id="food">

<goods id="food11">

<name>food11</name>

<price>12.90</price>

</goods>

<goods id="food12">

<name>food12</name>

<price>22.10</price>

<desc creator="hahawen">好东西推荐</desc>

</goods>

</cat>

<cat>

<goods id="tel21">

<name>tel21</name>

<price>1290</price>

</goods>

</cat>

<cat id="coat">

<goods id="coat31">

<name>coat31</name>

<price>112</price>

</goods>

<goods id="coat32">

<name>coat32</name>

<price>45</price>

</goods>

</cat>

<special id="hot">

<goods>

<name>hot41</name>

<price>99</price>

</goods>

</special>

</shop>



本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1676
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
能否用PowerPoint打开XML文件 能否用PowerPoint打开XML文件 Feb 19, 2024 pm 09:06 PM

XML文件可以用PPT打开吗?XML,即可扩展标记语言(ExtensibleMarkupLanguage),是一种被广泛应用于数据交换和数据存储的通用标记语言。与HTML相比,XML更加灵活,能够定义自己的标签和数据结构,使得数据的存储和交换更加方便和统一。而PPT,即PowerPoint,是微软公司开发的一种用于创建演示文稿的软件。它提供了图文并茂的方

Python中的XML数据转换为CSV格式 Python中的XML数据转换为CSV格式 Aug 11, 2023 pm 07:41 PM

Python中的XML数据转换为CSV格式XML(ExtensibleMarkupLanguage)是一种可扩展标记语言,常用于数据的存储和传输。而CSV(CommaSeparatedValues)则是一种以逗号分隔的文本文件格式,常用于数据的导入和导出。在处理数据时,有时需要将XML数据转换为CSV格式以便于分析和处理。Python作为一种功能强大

C#开发中如何处理XML和JSON数据格式 C#开发中如何处理XML和JSON数据格式 Oct 09, 2023 pm 06:15 PM

C#开发中如何处理XML和JSON数据格式,需要具体代码示例在现代软件开发中,XML和JSON是广泛应用的两种数据格式。XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,而JSON(JavaScript对象表示)是一种轻量级的数据交换格式。在C#开发中,我们经常需要处理和操作XML和JSON数据,本文将重点介绍如何使用C#处理这两种数据格式,并附上

您如何在PHP中解析和处理HTML/XML? 您如何在PHP中解析和处理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

如何使用 PHP 函数处理 XML 数据? 如何使用 PHP 函数处理 XML 数据? May 05, 2024 am 09:15 AM

使用PHPXML函数处理XML数据:解析XML数据:simplexml_load_file()和simplexml_load_string()加载XML文件或字符串。访问XML数据:利用SimpleXML对象的属性和方法获取元素名称、属性值和子元素。修改XML数据:使用addChild()和addAttribute()方法添加新元素和属性。序列化XML数据:asXML()方法将SimpleXML对象转换为XML字符串。实战案例:解析产品馈送XML,提取产品信息,转换并将其存储到数据库中。

使用Python实现XML中的数据校验 使用Python实现XML中的数据校验 Aug 10, 2023 pm 01:37 PM

使用Python实现XML中的数据校验引言:在现实生活中,我们经常会处理各种各样的数据,其中XML(可扩展标记语言)是一种常用的数据格式。XML具有良好的可读性和可扩展性,被广泛应用于各种领域,如数据交换、配置文件等。在处理XML数据时,我们经常需要对数据进行校验,以确保数据的完整性和正确性。本文将介绍如何使用Python实现XML中的数据校验,并给出相应的

使用Python解析带有命名空间的XML文档 使用Python解析带有命名空间的XML文档 Aug 09, 2023 pm 04:25 PM

使用Python解析带有命名空间的XML文档XML是一种常用的数据交换格式,能够适应各种应用场景。在处理XML文档时,有时会遇到带有命名空间(namespace)的情况。命名空间可以防止不同XML文档中元素名的冲突,提高了XML的灵活性和可扩展性。本文将介绍如何使用Python解析带有命名空间的XML文档,并给出相应的代码示例。首先,我们需要导入xml.et

在Java中使用Jackson库将POJO转换为XML? 在Java中使用Jackson库将POJO转换为XML? Sep 18, 2023 pm 02:21 PM

Jackson是一个基于Java的库,它对于将Java对象转换为JSON以及将JSON转换为Java对象非常有用。JacksonAPI比其他API更快,需要更少的内存区域,并且适合大型对象。我们使用XmlMapper类的writeValueAsString()方法将POJO转换为XML格式,并且需要将相应的POJO实例作为参数传递给此方法。语法publicStringwriteValueAsString(Objectvalue)throwsJsonProcessingException示例imp

See all articles