8bba46dba9043c254e6eef1aa664e6f0

XMLReader is fast and uses little memory. Here's something I came up with, but need a little bit of refactoring on the array creation meathod.

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
class XML_QNC
 {
  private $reader   = "";
  private $section  = "";
  private $callback = "";
  
  function XML_QNC($data, $section, $callback="", $type=0)
   {
    $this->reader   = new XMLReader();
    $this->section  = $section;
    $this->callback = $callback;

    if($type === 0)
     {
      // File
      $this->reader->open($data); 
     }
    else
     {
      // String
      $this->reader->XML($data);
     }
   }

  // http://us2.php.net/manual/en/ref.domxml.php#71493
  // Need to see if we can optimize this function.
  function xml2array($domnode)
   {
    $nodearray = array();
    $domnode   = $domnode->firstChild;

     while(!is_null($domnode))
      {
       $currentnode = $domnode->nodeName;

       switch ($domnode->nodeType)
        {
         case XML_TEXT_NODE:
          if(!(trim($domnode->nodeValue) == "")) $nodearray['cdata'] = $domnode->nodeValue;
         break;

         case XML_ELEMENT_NODE:
          if($domnode->hasAttributes())
           {
            $elementarray = array();
            $attributes   = $domnode->attributes;

            foreach($attributes as $index => $domobj)
             {
              $elementarray[$domobj->name] = $domobj->value;
             }
           }
         break;
        }

       if($domnode->hasChildNodes())
        {
         $nodearray[$currentnode][] = $this->xml2array($domnode);

         if(isset($elementarray))
          {
           $currnodeindex = count($nodearray[$currentnode]) - 1;
           $nodearray[$currentnode][$currnodeindex]['@'] = $elementarray;
          }
        }
       else
        {
         if(isset($elementarray) && $domnode->nodeType != XML_TEXT_NODE)
          {
           $nodearray[$currentnode]['@'] = $elementarray;
          }
        }
       $domnode = $domnode->nextSibling;
      }
    return $nodearray;
   }

  function parseIt()
   {
    while($this->reader->read())
     {
      if($this->reader->nodeType == 1 &&
         $this->reader->localName == $this->section)
       {
        do
         { 
          // Expand the rest of the data
          $element = $this->reader->expand(); 

          // Call back
          $call = $this->callback;
          $call($this->xml2array($element));
         }while($this->reader->next($this->section)); 
        break; 
       } 
     }
   } 
 }

Refactorings

No refactoring yet !

Avatar

lilJon

June 14, 2008, June 14, 2008 17:26, permalink

No rating. Login to rate!

Doesn't simpleXML do that?

http://ca3.php.net/SimpleXML

42e1363a474387e41af8f8219797e112

James Stansfield

June 17, 2008, June 17, 2008 11:07, permalink

No rating. Login to rate!

I agree, why reinvent something that is a part of PHP's core?

44522fc90c3828034bf947f635fff4ce

Nick Stinemates

June 30, 2008, June 30, 2008 03:54, permalink

No rating. Login to rate!

Last question.

Why parse to an array when you can parse to a Model object?

8bba46dba9043c254e6eef1aa664e6f0

ellisgl.myopenid.com

July 18, 2008, July 18, 2008 18:22, permalink

No rating. Login to rate!

@lilJon: Try parsing out a 5 gig XML.
@James: XMLReader is fast and uses little memory. Also it can do big files.
@Nick: This was just a quick test of something basically.

Your refactoring





Format Copy from initial code

or Cancel