0

I am new to work with XML files. I've been trying to load the an XML document with the following format as object or array: After the this edit

<?xml version="1.0"?>
<xdm:Device xmlns:xdm="http://www.example.com/schemas/imaging/con/xdm/1.1/" 
           xmlns:dd="http://www.example.com/schemas/imaging/con/dictionaries/1.0/" 
           xmlns:bsi="http://www.example.com/schemas/imaging/con/bsi/2003/08/21" 
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
           xmlns:count="http://www.example.com/schemas/imaging/con/counter/2006/01/13" 
           xmlns:media="http://www.example.com/schemas/imaging/con/media/2006/01/13/" 
           xmlns:xsi="http://www.example.org/2001/XMLSchema-instance" 
           xmlns:tt="http://www.example.com/schemas/imaging/con/capabilities/1.1/" 
           xmlns:pwg="http://www.example.com/schemas/imaging/con/pwg/sm/1.0/">
    <xdm:Information>        
        <xdm:Component id="system" componentType="system">
            <dd:MakeAndModel>Samsung LaserJet ML220</dd:MakeAndModel>
            <dd:Description>Blackand while printer</dd:Description>
            <dd:ProductNumber>XB3zzz</dd:ProductNumber>
            <dd:Manufacturer>
                <dd:Name>Samsung</dd:Name>
            </dd:Manufacturer>
        </xdm:Component>
    </xdm:Information>    
</xdm:Device>

I would like to get from every entrance for instance the MakeAndModel, Description, Manufacturer, etc.

I am trying to load the code with the following code currently, but I've tried a lot of things:

$xmlString = file_get_contents('test.xml');
$xml = simplexml_load_string($xmlString); 
var_dump($xml);

I have tried with other simpler XML documents and it works fine. But with my document it does not work, it loads an empty object instead. The file does not have a title. I read in php.net the following in one of the examples:

// The file test.xml contains an XML document with a root element // and at least an element /[root]/title.

How can I achieve load this XML to array or Object?

Edit2:

When I use a simple XML file from example var_dump outputs the following:

[root@windows8 csvmail]# php ppp.php 
object(SimpleXMLElement)#1 (1) {
  ["movie"]=>
  object(SimpleXMLElement)#2 (5) {
    ["title"]=>
    string(22) "PHP: Behind the Parser"

Whit the real file if get the following:

[root@windows8 csvmail]# php ppp.php 
object(SimpleXMLElement)#1 (0) {
}
[root@windows8 csvmail]# 
9
  • 2
    You are determining it to be empty by var_dump($xml)? SimpleXML has special implementations for iteration and variable dumping, making it confusing to understand what you're seeing when you try to debug with var_dump(). You may not, for example, see nested nodes dumped as you may be expecting. If you post specific details about what you are trying to retrieve from this XML, we can help a little better. The XML namespaces, for example, are notoriously confusing to work with using SimpleXML. Commented Jul 17, 2015 at 16:03
  • 1
    The bit in the docs about /root/title isn't exactly as it sounds. There must be at least one node dested under the root node, and in your XML, the <xdm:Device> appears to be the root node based on the fragment you posted. Commented Jul 17, 2015 at 16:06
  • 2
    I mean to say it may look empty like (object)SimpleXML {} but is not actually empty because of the way SimpleXML traverses nodes (especially the namespaces). If loading it failed, it would be (bool)false. To actually see what's inside it despite it looking empty, you need to attempt to retrieve nodes within. We can help with that. Commented Jul 17, 2015 at 16:06
  • 1
    I can't find a decent duplicate at the moment (there's a lot of bad advice around), but working with namespaces (that's all the XML tags with : in them) in SimpleXML really isn't that hard: you just use the ->children() method to select the namespace, then carry on accessing the bits of the document you need. And as Michael Berkowski says, don't trust var_dump. Commented Jul 17, 2015 at 16:30
  • 2
    @wti The namespaces may not mean anything to you, but removing them completely leads to invalid XML, and the fact that they are different is central to understanding how to use this XML. I've edited the example to be valid, and will give a quick answer on how to start working with it. Commented Jul 17, 2015 at 17:59

1 Answer 1

2

The nodes with : in them are in "XML namespaces". They are used to mix multiple types of data into one file, even if the tag names would otherwise collide.

At the top of the file, the xmlns:... attributes associate prefixes (which could be changed by whatever is generating the file) with URLs (which act as a permanent identifier for a particular type of data).

To access them with SimpleXML, you use the ->children() method to "select" the namespace. You can rely on the prefix not changing, or you can store the permanent identifiers in a variable or constant, and use that, like this:

// Defining my own ways of referring to the namespaces, regardless of prefix used
define('XMLNS_HP_XDM_1_1', 'http://www.hp.com/schemas/imaging/con/xdm/1.1/');
define('XMLNS_HP_DICT_1_0', 'http://www.hp.com/schemas/imaging/con/dictionaries/1.0/');

// Load the XML in the normal way
$sx = simplexml_load_string($xml);

// Switch to the first namespace, and look at the first Component
$component = $sx->children(XMLNS_HP_XDM_1_1)->Information->Component;

// Attributes with no : in are technically in no namespace at all,
// so we have to switch back to the null namespace using attributes()
$component_id = (string)$component->attributes(null)->id;

// Switch to the second namespace to find the MakeAndModel
$make_and_model = (string)$component->children(XMLNS_HP_DICT_1_0)->MakeAndModel;

echo "$component_id : $make_and_model";

[Live Demo]

For how to loop over multiple elements, and other basic usage, see the examples in the PHP manual.

Sign up to request clarification or add additional context in comments.

1 Comment

Glad you found this question. I hadn't had time to return to it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.