Jeremy Newman : add XML parsing to array class

Jeremy Newman jnewman at wine.codeweavers.com
Tue Jan 19 12:45:30 CST 2016


Module: website
Branch: master
Commit: f5cf99650775aa1a07673050fc9b41599a2bf6fe
URL:    http://source.winehq.org/git/website.git/?a=commit;h=f5cf99650775aa1a07673050fc9b41599a2bf6fe

Author: Jeremy Newman <jnewman at codeweavers.com>
Date:   Tue Jan 19 11:24:00 2016 -0600

add XML parsing to array class

---

 include/XMLToArray.php | 189 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 189 insertions(+)

diff --git a/include/XMLToArray.php b/include/XMLToArray.php
new file mode 100644
index 0000000..7996c5e
--- /dev/null
+++ b/include/XMLToArray.php
@@ -0,0 +1,189 @@
+<?php
+/*
+    loads an XML file into an array
+      Use transverse_array() after parsing to get a nice dump
+    by Jeremy Newman <jnewman at codeweavers.com>
+*/
+
+class XMLToArray
+{
+    var $data;
+    var $filename;
+    var $traverse_array = array();
+    var $error;
+
+    /** PUBLIC
+     * Constructor: init the object. Define the parsing mode.
+     */
+    public function __construct ()
+    {
+        return true;
+    }
+
+    /** PUBLIC
+     * Parse a text string containing valid XML into a multidimensional array
+     */
+    public function parse ()
+    {
+        if (!$this->data and isset($this->filename))
+        {
+            if (file_exists($this->filename))
+            {
+                $this->data = join("", @file($this->filename));
+            }
+            else
+            {
+                $message = "XML ERROR: {$this->filebname} NOT FOUND!";
+                $this->error = $message;
+                error_log("$message\n");
+                return 0;
+            }
+        }
+        
+        if (!$this->data)
+        {
+            $message = "XML ERROR: no data to be parsed!";
+            error_log("$message\n");
+            $this->error = $message;
+            return 0;
+        }
+    
+        $this->data = trim($this->data);
+        $vals = $index = $array = array();
+        $parser = xml_parser_create("");
+        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
+        xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
+        if (!xml_parse_into_struct($parser, $this->data, $vals, $index))
+        {
+            $message = "XML ERROR: ".xml_error_string(xml_get_error_code($parser))." at line ".xml_get_current_line_number($parser);
+            $this->error = $message;
+            error_log("$message\n");
+            return 0;
+        }
+        xml_parser_free($parser);
+    
+        $i = 0;
+    
+        $tagname = $vals[$i]['tag'];
+        if (isset($vals[$i]['attributes']))
+        {
+            $array[$tagname]['@'] = $vals[$i]['attributes'];
+        }
+        else
+        {
+            $array[$tagname]['@'] = array();
+        }
+    
+        $array[$tagname]["#"] = $this->depth($vals, $i);
+    
+        return $array;
+    }
+
+    /** PRIVATE
+     * this goes through the tags in the mode 2 parsing. called from parse_mode2
+     */
+    private function depth ($vals, &$i)
+    {
+        $children = array(); 
+    
+        if (isset($vals[$i]['value']))
+        {
+            array_push($children, $vals[$i]['value']);
+        }
+    
+        while (++$i < count($vals))
+        { 
+            switch ($vals[$i]['type'])
+            { 
+               case 'open': 
+    
+                    if (isset($vals[$i]['tag']))
+                    {
+                        $tagname = $vals[$i]['tag'];
+                    }
+                    else
+                    {
+                        $tagname = '';
+                    }
+    
+                    if (isset($children[$tagname]))
+                    {
+                        $size = sizeof($children[$tagname]);
+                    }
+                    else
+                    {
+                        $size = 0;
+                    }
+    
+                    if (isset($vals[$i]['attributes']))
+                    {
+                        $children[$tagname][$size]['@'] = $vals[$i]["attributes"];
+                    }
+    
+                    $children[$tagname][$size]['#'] = $this->depth($vals, $i);
+                    
+                    break; 
+    
+                case 'cdata':
+                    array_push($children, $vals[$i]['value']); 
+                    break; 
+    
+                case 'complete': 
+                    $tagname = $vals[$i]['tag'];
+    
+                    if (isset($children[$tagname]))
+                    {
+                        $size = sizeof($children[$tagname]);
+                    }
+                    else
+                    {
+                        $size = 0;
+                    }
+    
+                    if (isset($vals[$i]['value']))
+                    {
+                        $children[$tagname][$size]["#"] = $vals[$i]['value'];
+                    }
+                    else
+                    {
+                        $children[$tagname][$size]["#"] = '';
+                    }
+    
+                    if (isset($vals[$i]['attributes']))
+                    {
+                        $children[$tagname][$size]['@'] = $vals[$i]['attributes'];
+                    }
+                    break; 
+    
+                case 'close':
+                    return $children; 
+                    break;
+            } 
+    
+        } 
+        return $children;
+    }
+
+    /** PUBLIC
+     * dump an array to the PHP full var path (useful for debugging)
+     */
+    public function traverse ($array, $arrName = "array", $level = 0)
+    {
+        foreach ($array as $key => $val)
+        {
+            if (is_array($val))
+            {
+                $this->traverse($val, $arrName . "[" . $key . "]", $level + 1);
+            }
+            else
+            {
+                $this->traverse_array[] = '$' . $arrName . '[' . $key . '] = "' . $val . "\"";
+            }
+        }
+        return 1;
+    }
+
+}
+
+?>




More information about the wine-cvs mailing list