PHP流式读取XML文件

  之前在项目中有读取XML的需求,一开始采用的是simplexml将xml文件全部load到内存里,然后一个节点一个节点读的方式,后来随着XML文件的增大,内存被撑爆了。于是赶紧想办法,于是有了流式读取。一开始老大给了我一个封装XMLReader的类,但是我发现这个类不是很符合我的要求,于是又把XMLReader按我的要求重新封装了一遍,在此感谢老大moon。

  目前我的类非常简单就提供几个方法,我提供了Demo供大家参考使用。话不多说上代码

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

<?php

/**

 *

 * @author gaoran

 * Another new parser for (X|HT)ML(stream version)

 * @version 1.0 2014-06-02 18:10:00

 * 感谢我的老大moon,之前moon写了一个XMLParser的类,但是我觉得不是我想要的,于是自己重新封装了一遍,自我感觉简单,好用

 */

class New_XMLParser extends
XMLReader{

    private
$_tagName;

    /**

     * 设置打开xml文件的路径

     */

    public
function open($xml,$encoding=null,$option=null){

        parent::open($xml, $encoding, $option);

    }

    /**

     * 设置要读取数据的节点名称

     */

    public
function setTagName($tagName){

        $this->_tagName = $tagName;

    }

    /**

     * 每次读取一个节点数据,以数组格式返回

     */

    public
function getData(){

        if(!$this->_tagName){return
false;}

        while($this->read()){

            $tagName
= $this->name;

            if($this->nodeType == XMLReader::ELEMENT && $this->_tagName == $tagName){

                $dom
= new DOMDocument(‘1.0‘, ‘utf-8‘);

                $d
= $dom->importNode($this->expand(), true);

                //$dom->appendChild($d);

                $appinfo
= $this->domToArray($d);

                return
$appinfo;

            }

        }

        return
false;

    }

    /**

     *

     * @param SimpleXMLElement|DOMDocument|DOMNode $obj SimpleXMLElement, DOMDocument or DOMNode instance

     * @return array Array representation of the XML structure.

     */

    public
static function domToArray($obj) {

        if
($obj instanceof DOMNode) {

            $obj
= simplexml_import_dom($obj);

        }

        $result
= array();

        $namespaces
= array_merge(array(‘‘
=> ‘‘), $obj->getNamespaces(true));

        self::_toArray($obj, $result, ‘‘, array_keys($namespaces));

        return
$result;

    }

    protected
static function _toArray($xml, &$parentData, $ns, $namespaces) {

        $data
= array();

        foreach
($namespaces
as $namespace) {

            foreach
($xml->attributes($namespace, true) as
$key => $value) {

                if
(!empty($namespace)) {

                    $key
= $namespace
. ‘:‘ . $key;

                }

                $data[‘@‘
. $key] = (string)$value;

            }

            foreach
($xml->children($namespace, true) as
$child) {

                self::_toArray($child, $data, $namespace, $namespaces);

            }

        }

        $asString
= trim((string)$xml);

        if
(empty($data)) {

            $data
= $asString;

        } elseif
(!empty($asString)) {

            $data[‘@‘] = $asString;

        }

        if
(!empty($ns)) {

            $ns
.= ‘:‘;

        }

        $name
= $ns . $xml->getName();

        if
(isset($parentData[$name])) {

            if
(!is_array($parentData[$name]) || !isset($parentData[$name][0])) {

                $parentData[$name] = array($parentData[$name]);

            }

            $parentData[$name][] = $data;

        } else
{

            $parentData[$name] = $data;

        }

    }

    /*

     * 关闭XML流

     */

    public
function close(){

        parent::close();

    }

}

class
Demo{

    public
function run(){

        $im
= new New_XMLParser();

        $im->open(‘yingyonghui‘);

        $im->setTagName("webName");

        print_r($im->getData());

        $im->setTagName("webSiteUrl");

        print_r($im->getData());

        $im->setTagName("app");

        print_r($im->getData());

        //$im->open(‘yingyonghui‘);

        $i
= 0;

        while($i
< 3 && $appinfo
= $im->getData()){

            print_r($appinfo);

            $i
++;

        }

        $im->close();

    }

}

$d = new Demo();

$d->run();

  

目前够用了,以后继续改进吧,欢迎大家拍砖,一起进步完善。

时间: 2024-11-06 17:06:10

PHP流式读取XML文件的相关文章

使用spreadsheet-reader流式读取超大excel文件

github:https://github.com/nuovo/spreadsheet-reader 最近有一个读取超大excel文件的功能需求,使用的phpexcel,有严重的内存泄露问题,暂时还未找到解决方案. spreadsheet-reader是流式读取excel的,对于大多数格式的excel都能正常的读取,且内存消耗很小. PS:其中遇到的坑 xlsx文件一定要标准,也就是必须是offce生成的,而不是wps之类的--被这个坑了很久 如果不正确会出现如下报错,个人猜测是文件头问题,建议

C#中常用的几种读取XML文件的方法

XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具.XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用.微软也提供了一系列类库来倒帮助我们在应用程序中存储XML文件. “在程序中访问

使用Pull解析器生成XML文件和读取xml文件

有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中:或者使用DOM API生成XML文件,或者也可以使用pull解析器生成XML文件,这里推荐大家使用Pull解析器. 一.布局界面 [html] view plaincopyprint? <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

OpenCV 读取.xml文件

OpenCV 只提供了读取和存储.xml和.yml 文件格式的函数. 读取.xml文件的C++例程如下: 1 cv::FileStorage fs; //OpenCV 读XML文件流 2 cv::Mat DepthData; //深度数据矩阵 3 std::string filename = "C:\\Users\\xzd\\Documents\\KinectFile\\2014-08-28\\16-32-30\\Depth0001.xml"; 4 // 待读取.XML文件名 5 6

Dom4j读取xml文件——JAVA

前几天,用Dom4j写了三个版本的读取XML文件,现在分享下. 第一版本: XML: <?xml version="1.0" encoding="UTF-8"?> <do-config> <do path="User/adduser" type="UserPackage.UserServlet"> <forward name="Success">AddSucc

C#读取XML文件的基类实现

刚到新单位,学习他们的源代码,代码里读写系统配置文件的XML代码比较老套,直接写在一个系统配置类里,没有进行类的拆分,造成类很庞大,同时,操作XML的读写操作都是使用SetAttribute和node.Attribute(name)方法,因此,想到结合之前所做的XML操作,完成了一个能够读取XML文件的基类,便于以后的使用. PS:即使再老套的代码,目前也不敢进行优化,一是水平不行,二是不敢. 使用静态扩展类,扩展了几个经常使用的类型,能够方便数据的读写. 操作XML的类,可以直接继承BaseL

Excel开发学习笔记:读取xml文件及csv文件

读取xml文件 有好多种读取xml的方式,xmlDOM比较常见,我使用了另外一种,它以数据流的方式打开文件并读取内容 Imports System.Xml  Dim group As New List(Of String)  Using reader As XmlReader = XmlReader.Create(OpenFileDialog2.FileName)      While reader.ReadToFollowing("group")          reader.Mo

读取XML文件的指定节点的值 并转换为Item

cmb_State_Send.ItemsSource = null; XmlDocument doc = new XmlDocument(); doc.Load("D:\\模板\\WorkstationState_Config.xml"); //加载Xml文件 XmlElement rootElem = doc.DocumentElement; //获取根节点 XmlNode xn = rootElem.SelectSingleNode("//Workstation[@Nam

Java使用相对路径读取xml文件

java使用相对路径读取xml文件 博客分类: java javaXMLJavaWeb 一.xml文件一般的存放位置有三个: 1.放在WEB-INF下: 2.xml文件放在/WEB-INF/classes目录下或classpath的jar包中: 3.放在与解析它的java类同一个包中,不一定是classpath: 二.相对应的两种使用相对路径的读取方法: 方法一:(未验证) 将xml文件放在WEB-INF目录下,然后 程序代码: InputStream is=getServletContext(