0

I want get the whole XML contents, but the results only show node value, node attributes are missing.

XML File:

<main>
    <people num="1">
        <name num1="1">Jack</name>
        <age num2="1">50</age>
    </people>   
</main>

The code is

$xml = simplexml_load_file("c:/www/Mongo/test2.xml");
$xml1=$xml->people;
var_dump($xml1);

Result:

object(SimpleXMLElement)#2 (3) { ["@attributes"]=> array(1) { ["num"]=>string(1) "1" } ["name"]=> string(4) "Jack" ["age"]=> string(2) "50" }

Name&Age node attributes are missing. I know the attributes could get by $xml->people->name, but how to get it only use $xml->people

3
  • attributes could be got when no node value Commented Apr 6, 2015 at 17:25
  • It would be great if you could update your question showing the output you would like to see. Commented Apr 6, 2015 at 17:39
  • I want get the <name> attribute and value in the same time Commented Apr 6, 2015 at 17:40

2 Answers 2

3

The problem is that leaf nodes (e.g. name) can have both attributes (num1 = "1") and a value ("Jack"). Just how should that be represented when converted into an array?

If we set $array['people']['name'] = "Jack", where would we store the attributes? We cannot use $array['people']['name']['@attributes'] = ['num1' => 1] as that would overwrite the "Jack" value.

The code below presents one solution, where each (leaf) value is wrapped in a 'value' element, e.g. $array['people']['name']['value'] = "Jack" and the attributes have the standard '@attributes' key, e.g. $array['people']['name']['@attributes'] = ['num1' => 1]. This would work for simple XML like the one in your question but may not be suitable for more complicated documents.

Reading the comments I understand that you actually want to convert the XML into JSON, so that is what the following code does in the end:

// Some example XML (some elements added)
$src = <<<EOS
<main>
    <people num="1">
        <name num1="1">Jack</name>
        <age num2="1">50</age>
        <skills what="ever">
            <skill type="minor">Cookie munching</skill>
            <skill type="major">Cake gobbling</skill>
            <skill>Candy gulping</skill>
        </skills>
    </people>
</main>
EOS;

// Create a DOM element from XML    
$dom = new DOMDocument();
$dom->loadXML($src);

// Use a XPath query to get all leaf nodes (elements without
// element child nodes)
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//*[not(*)]') as $leaf) {
    // Create a new <value> element for each leaf node, moving
    // the leaf value (first child) into that node.
    // E.g. <name num1="1">Jack</name>
    //   => <name num1="1"><value>Jack</value></name>
    $value = $dom->createElement('value');
    $value->appendChild($leaf->firstChild);
    $leaf->insertBefore($value);
}

// Turn into SimpleXMLElement and covert to JSON
$xml  = simplexml_import_dom($dom);
$json = json_encode($xml, JSON_PRETTY_PRINT);
echo $json, PHP_EOL;

Output:

{
    "people": {
        "@attributes": {
            "num": "1"
        },
        "name": {
            "@attributes": {
                "num1": "1"
            },
            "value": "Jack"
        },
        "age": {
            "@attributes": {
                "num2": "1"
            },
            "value": "50"
        },
        "skills": {
            "@attributes": {
                "what": "ever"
            },
            "skill": [
                {
                    "@attributes": {
                        "type": "minor"
                    },
                    "value": "Cookie munching"
                },
                {
                    "@attributes": {
                        "type": "major"
                    },
                    "value": "Cake gobbling"
                },
                {
                    "value": "Candy gulping"
                }
            ]
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Here is a better solution using json_encode, json_decode

echo '<pre>';
$xml = simplexml_load_file("n.xml");
$xml=json_decode(json_encode($xml),TRUE);
$xml1=$xml['people'];
print_r($xml1);
echo '<br>';
print_r($xml['people']['@attributes']['num']);

Output:

Array
(
    [@attributes] => Array
        (
            [num] => 1
        )

    [name] => Jack
    [age] => 50
)

1

So one last suggestion , probably you can change your XML data something like this

<?xml version="1.0" encoding="UTF-8"?>
<main>
    <people num="1">
        <name num1="1"><first_name>Jack</first_name></name>
        <age num2="1"><years>50</years></age>
    </people>   
</main>

Output:

    Array
(
    [people] => Array
        (
            [@attributes] => Array
                (
                    [num] => 1
                )

            [name] => Array
                (
                    [@attributes] => Array
                        (
                            [num1] => 1
                        )

                    [first_name] => Jack
                )

            [age] => Array
                (
                    [@attributes] => Array
                        (
                            [num2] => 1
                        )

                    [years] => 50
                )

        )

)

this should work for you. :)

2 Comments

hi, my purpose is convert the above xml to json. But the attributes are missing when converted to json
My next code is $json = json_encode($xml1); echo $json;

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.