Easily parse XML documents with PHP 5.0

Source: Internet
Author: User
Tags abstract foreach functions php code trim

When you use sax, you have to build 3 functions yourself, and you want to use the three function directly to return the data, requiring strong logic. In the process of dealing with different structure of XML, but also to reconstruct these three functions, trouble!

It's better to use DOM, but he sees every node as a nodal, and it's a lot of code to write, Trouble!

There are a lot of open source XML parsing class library, had seen a few before, but in the mind always feel not steadfast, feeling always follow someone else's butt behind.

These days in the Java, very tired, so decided to change the head, write some PHP code, in order to prevent the XML parsing process again to make me puzzled, it took a day to write the following XML parsing class, so there is the following things.

The implementation is done by wrapping "analytic results of Sax methods". In general, for me it is very practical, performance is also possible, basically can complete most of the processing requirements.

Function:

1, query/Add/modify/delete the basic XML file nodes.

2, export all the data of the XML file into an array.

3, the entire design using OO way, in the operation of the result set, the use of methods similar to the DOM

Disadvantages:

1, each node preferably with an ID (see the following example), each "node name" = "Node's label _ Node ID", if this ID value is not set, the program will automatically give him an ID, this ID is the node in his ancestor node in the number of positions, starting from 0.

2. When querying a node, you can use the "|" Symbolic Connection "node name" to proceed. These "node names" are the names of the ancestor nodes that are written in order.

Instructions for use:

Run the following example, and you can see how the function is used on the execution results page.

The code is implemented through PHP5 and cannot function properly in PHP4.

Since you have just finished, so there is no documentation, the following example shows only part of the function, the code is not very difficult, if you want to know more features, you can study the source code.

Directory structure:

test.php

Test.xml

xml/simpledocumentbase.php

xml/simpledocumentnode.php

xml/simpledocumentroot.php

xml/simpledocumentparser.php

File: Test.xml

Hualian

Beijing Changan Street-No. No. 9999 supermarket chain food11 12.90 food12 22.10 > Good thing to recommend tel21 1290 coat31 112 coat32 hot41< /name>

File: test.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 "

File: simpledocumentparser.php

/**

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

*

* @author Hahawen (older youth)

* @since 2004-12-04

* @copyright Copyright (c), Nxcoder Group

*

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

*/

/**

* Class Simpledocumentparser

* Use SAX parse XML file, and build Simpledocumentobject

* All this pachage's is work to XML file, and 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);

}

}

? >

File: simpledocumentbase.php

/**

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

*

* @author Hahawen (older youth)

* @since 2004-12-04

* @copyright Copyright (c), Nxcoder Group

*

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

*/

/**

* Abstract class Simpledocumentbase

* Base class for XML file parse

* All this pachage's is work to XML file, and 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 \r\n";

}

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

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

$str. = "$prefixSpace nodetag>";

return $str;

}

function __destruct ()

{

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

}

}

? >

File: simpledocumentroot.php

/**

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

*

* @author Hahawen (older youth)

* @since 2004-12-04

* @copyright Copyright (c), Nxcoder Group

*

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

*/

/**

* Class Simpledocumentroot

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

* All this pachage's is work to XML file, and is action as DOM.

*

* @package SmartWeb.common.xml

* @version 1.0

*/

Class Simpledocumentroot extends Simpledocumentbase

{

Private $prefixStr = '

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);

}

}

? >

File: simpledocumentnode.php

/**

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

*

* @author Hahawen (older youth)

* @since 2004-12-04

* @copyright Copyright (c), Nxcoder Group

*

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

*/

/**

* Class Simpledocumentnode

* XML Node class, include Values/attributes/subnodes.

* All this pachage's is work to XML file, and 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);

}

}

? >

Here is the example run to the result:

The following is an array of the entire XML data returned through the function Getsavedata ()

Array

(

[Name] => Hualian

[Address] => Beijing Changan Street-No. No. 9999

[Desc] => supermarket chain

[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] => good things recommend

[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

)

)

)

The following is a SetValue () function that adds information to the root node and then displays the contents of the resulting XML file.

Hualian

Chang ' An Street, Beijing, No. No. 9999

Supermarket chains

123456789

Food11

12.90

food12

22.10

good thing recommended

tel21

1290

coat31

112

Coat32

hot41



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.