Author Topic: Help with XML2Array  (Read 206 times)

0 Members and 1 Guest are viewing this topic.

Offline BulletSpongeTopic starter

  • Irregular
  • Posts: 1
    • View Profile
Help with XML2Array
« on: July 03, 2009, 06:27:52 PM »
Hi all,

I'm new to PHP (.net background) and I'm having trouble with an import of an XML file into a multi-dimensional array.  I did some digging and with the help of the internet was able to find some code that works fairly well outside of one part.

I have included the PHP function I found to pull the XML and a trimmed down version of the XML.

function xml2array($FilePath$get_attributes 1$priority 'tag')
{
    
$contents "";
    if (!
function_exists('xml_parser_create'))
    {
        return array ();
    }
    
$parser xml_parser_create('');
    if (!(
$fp = @ fopen($FilePath'rb')))
    {
        return array ();
    }
    while (!
feof($fp))
    {
        
$contents .= fread($fp8192);
    }
    
fclose($fp);
    
xml_parser_set_option($parserXML_OPTION_TARGET_ENCODING"UTF-8");
    
xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0);
    
xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1);
    
xml_parse_into_struct($parsertrim($contents), $xml_values);
    
xml_parser_free($parser);
    if (!
$xml_values)
        return; 
//Hmm...
    
$xml_array = array ();
    
$parents = array ();
    
$opened_tags = array ();
    
$arr = array ();
    
$current = & $xml_array;
    
$repeated_tag_index = array (); 
    foreach (
$xml_values as $data)
    {
        unset (
$attributes$value);
        
extract($data);
        
$result = array ();
        
$attributes_data = array ();
        if (isset (
$value))
        {
            if (
$priority == 'tag')
                
$result $value;
            else
                
$result['value'] = $value;
        }
        if (isset (
$attributes) and $get_attributes)
        {
            foreach (
$attributes as $attr => $val)
            {
                if (
$priority == 'tag')
                    
$attributes_data[$attr] = $val;
                else
                    
$result['attr'][$attr] = $val//Set all the attributes in a array called 'attr'
            
}
        }
        if (
$type == "open")
        { 
            
$parent[$level -1] = & $current;
            if (!
is_array($current) or (!in_array($tagarray_keys($current))))
            {
                
$current[$tag] = $result;
                if (
$attributes_data)
                    
$current[$tag '_attr'] = $attributes_data;
                
$repeated_tag_index[$tag '_' $level] = 1;
                
$current = & $current[$tag];
            }
            else
            {
                if (isset (
$current[$tag][0]))
                {
                    
$current[$tag][$repeated_tag_index[$tag '_' $level]] = $result;
                    
$repeated_tag_index[$tag '_' $level]++;
                }
                else
                { 
                    
$current[$tag] = array (
                        
$current[$tag],
                        
$result
                    
); 
                    
$repeated_tag_index[$tag '_' $level] = 2;
                    if (isset (
$current[$tag '_attr']))
                    {
                        
$current[$tag]['0_attr'] = $current[$tag '_attr'];
                        unset (
$current[$tag '_attr']);
                    }
                }
                
$last_item_index $repeated_tag_index[$tag '_' $level] - 1;
                
$current = & $current[$tag][$last_item_index];
            }
        }
        elseif (
$type == "complete")
        {
            if (!isset (
$current[$tag]))
            {
                
$current[$tag] = $result;
                
$repeated_tag_index[$tag '_' $level] = 1;
                if (
$priority == 'tag' and $attributes_data)
                    
$current[$tag '_attr'] = $attributes_data;
            }
            else
            {
                if (isset (
$current[$tag][0]) and is_array($current[$tag]))
                {
                    
$current[$tag][$repeated_tag_index[$tag '_' $level]] = $result;
                    if (
$priority == 'tag' and $get_attributes and $attributes_data)
                    {
                        
$current[$tag][$repeated_tag_index[$tag '_' $level] . '_attr'] = $attributes_data;
                    }
                    
$repeated_tag_index[$tag '_' $level]++;
                }
                else
                {
                    
$current[$tag] = array (
                        
$current[$tag],
                        
$result
                    
); 
                    
$repeated_tag_index[$tag '_' $level] = 1;
                    if (
$priority == 'tag' and $get_attributes)
                    {
                        if (isset (
$current[$tag '_attr']))
                        { 
                            
$current[$tag]['0_attr'] = $current[$tag '_attr'];
                            unset (
$current[$tag '_attr']);
                        }
                        if (
$attributes_data)
                        {
                            
$current[$tag][$repeated_tag_index[$tag '_' $level] . '_attr'] = $attributes_data;
                        }
                    }
                    
$repeated_tag_index[$tag '_' $level]++; //0 and 1 index is already taken
                
}
            }
        }
        elseif (
$type == 'close')
        {
            
$current = & $parent[$level -1];
        }
    }
    return (
$xml_array);
}

Here's a sample of the XML
Code: [Select]
<?xml version="1.0"?>
<Inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\WebInventory\WebInventoryExtract.xsd">
   <Unit rec_id="189*R131">
      <class>Class 1</class>
      <brand>ACME</brand>
      <status>AVAILABLE</status>
      <Option>
         <option_code>11426</option_code>
         <option_desc>Opt 1</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>11562</option_code>
         <option_desc>Opt 2</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>87166</option_code>
         <option_desc>Opt 3</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
   </Unit>
   <Unit rec_id="189*R132">
      <class>Class 1</class>
      <brand>ACME</brand>
      <status>AVAILABLE</status>
      <Option>
         <option_code>11426</option_code>
         <option_desc>Opt 1</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>11562</option_code>
         <option_desc>Opt 5</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>87166</option_code>
         <option_desc>Opt 6</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
   </Unit>
   <Unit rec_id="189*R133">
      <class>Class 2</class>
      <brand>ACME</brand>
      <status>AVAILABLE</status>
      <Option>
         <option_code>11426</option_code>
         <option_desc>Opt x</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>11562</option_code>
         <option_desc>Opt y</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
      <Option>
         <option_code>87166</option_code>
         <option_desc>Opt z</option_desc>
         <option_qty>1.00</option_qty>
      </Option>
   </Unit>
   <Unit rec_id="189*R134">
      <class>Class 2</class>
      <brand>ACME</brand>
      <status>SOLD</status>
   </Unit>
</Inventory>

Now the problem I am running into is this;
I can get the values for the "units" and it's class, brand, and status values, but I have NO idea how to retrieve the "Option" values.  When I use the "print_r" function it spits out "Array".

What am I missing?

Thanks for your help :)
« Last Edit: July 03, 2009, 06:28:52 PM by BulletSponge »

Offline Bendude14

  • Enthusiast
  • Posts: 411
  • Gender: Male
  • Live for Today
    • View Profile
    • Mandurah Web Designs
Re: Help with XML2Array
« Reply #1 on: July 04, 2009, 02:41:51 AM »
what does var_dump() display?


Offline Dj Kat

  • Addict
  • Posts: 1,507
  • Gender: Male
    • View Profile
Re: Help with XML2Array
« Reply #2 on: July 04, 2009, 04:18:16 AM »
PHP already has excellent xml parsers you don't really need a custom function. Try this
Code: [Select]
<?php
// parse the xml (change the path to suit your needs)
$xml=simplexml_load_file("inventory.xml");


// loop through each unit
foreach($xml->Unit as $unit){

// get unit attributes
$attriubtes=$unit->attributes();
echo "<b>rec_id:</b> {$attriubtes['rec_id']} <br />";

// loop through unit options
foreach($unit->Option as $option){
echo "<b>option_code:</b> {$option->option_code} <br />";
echo "<b>option_desc:</b> {$option->option_desc} <br />";
echo "<b>option_qty:</b> {$option->option_qty} <br />";
}
echo "<hr />";

}