Jump to content

Help with XML2Array


BulletSponge

Recommended Posts

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($fp, 8192);
    }
    fclose($fp);
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($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($tag, array_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

<?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 :)

Link to comment
https://forums.phpfreaks.com/topic/164710-help-with-xml2array/
Share on other sites

PHP already has excellent xml parsers you don't really need a custom function. Try this

<?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 />";

}

Link to comment
https://forums.phpfreaks.com/topic/164710-help-with-xml2array/#findComment-868728
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.