Search code examples
xmlreader

xmlReader in PHP- Problems getting it to work right


I have a pretty large file that I need to parse in php, so I'm using xmlReader. I've just started playing around with xml and am having some problems....

Here is how the xml is structured...

<?xml version="1.0" encoding="utf-8"?>
    <devices>
        <os name="os1">
            <device user_agent="uaValue1">
                <device_name>name1</device_name>
                <device_os>osValue1</device_os>
            </device>
            <device user_agent="uaValue2">
                <device_name>name2</device_name>
                <device_os>osValue2</device_os>
            </device>   
        </os>
        <os name="os2">
            <device user_agent="uaValue3">
                <device_name>name3</device_name>
                <device_os>osValue5</device_os>
            </device>
            <device user_agent="uaValue4">
                <device_name>name4</device_name>
                <device_os>osValue4</device_os>
            </device>   
        </os>
        <manufacturer name="mf1">
            <device user_agent="uaValue5">
                <device_name>name5</device_name>
                <device_os>osValue5</device_os>
            </device>
            <device user_agent="uaValue6">
                <device_name>name6</device_name>
                <device_os>osValue6</device_os>
            </device>       
        </manufacturer>
        <manufacturer name="mf2">
            <device user_agent="uaValue7">
                <device_name>name7</device_name>
                <device_os>osValue7</device_os>
            </device>
            <device user_agent="uaValue8">
                <device_name>name8</device_name>
                <device_os>osValue8</device_os>
            </device>       
        </manufacturer> 
    </devices>

I am trying to use the following function to read the xml (where $findby will pass os or manufacturer / $atr_value is the attribute name for the $findby value / $ua_str is the user agent).

function get_data($findby,$atr_value,$ua_str) {
    $data['device_name'] = '';
    $data['device_os'] = '';

    $xml = new XMLReader;
    $xml->open('devices.xml');

    while($xml->read()) {
        if ($xml->name == $findby) {
            if ($xml->getAttribute('name') == $atr_value) {
                while($xml->read()) {
                    if ($xml->name == "device") {
                        if ($xml->getAttribute('user_agent') == $ua_str) {
                            while($xml->read()) {                               
                                if ($xml->name == "device_name") {
                                    $data['device_name'] = $xml->value;
                                }
                                if ($xml->name == "device_os") {
                                    $data['device_os'] = $xml->value;
                                }
                            }
                        }
                    }                   
                }
            }
        }
    }
    $xml->close();
    return $data;
}

By echoing a few values here and there, it seems to pull data down to the user agent, but won't get the device_name or device_os.

Obviously, this is not working. I was thinking that the xml can't be structured that way which could be the problem and an easy fix. However on one of my previous versions, it pulled the data but it was from the wrong user agent. So I'm thinking it is something in how I am trying to pull the data with the xmlReader.

Does anyone have any thoughts on why this does not work? Thank you...


Solution

  • You're not checking the tag type in the outer while loop. XMLReader sends you opening tags, closing tags, tag content, and you need to handle at least some of those events.

    In your outer loop, check $reader->nodeType == XMLReader::ELEMENT for an opening, XMLReader::END_ELEMENT for a closing, and XMLReader::TEXT for tag content. There are a lot of others too - see the PHP docs for this class (values 0-17).