0

I have an xml file that looks like this

<?xml version="1.0" encoding="UTF-8" ?>

<dates>
<date>
<Item Name="History" Type="List">
        <Item Name="received" Type="Date">2015/12/18 00:00</Item>
        <Item Name="accepted" Type="Date">2016/03/31 00:00</Item>
        <Item Name="aheadofprint" Type="Date">2016/04/14 00:00</Item>
        <Item Name="entrez" Type="Date">2016/04/15 06:00</Item>
        <Item Name="pubmed" Type="Date">2016/04/15 06:00</Item>
        <Item Name="medline" Type="Date">2016/04/15 06:00</Item>
    </Item>
</date>
<date>
<Item Name="History" Type="List">
        <Item Name="epublish" Type="Date">2016/05/23 00:00</Item>
        <Item Name="entrez" Type="Date">2016/07/12 06:00</Item>
        <Item Name="pubmed" Type="Date">2016/07/12 06:00</Item>
        <Item Name="medline" Type="Date">2016/07/12 06:00</Item>
        <Item Name="pmc-release" Type="Date">2017/01/01 00:00</Item>
    </Item>
</date>

</dates>

I am trying to get values of both the "name" attribute and the "date" attribute. I have used the code below

<?php

$xml = simplexml_load_file('dates.xml');

foreach( $xml->date->Item->children() as $v){
$k = 'date';
echo $k ."=". $v . "<br>";
}
?>

This code returns the following results

date=2015/12/18 00:00
date=2016/03/31 00:00
date=2016/04/14 00:00
date=2016/04/15 06:00
date=2016/04/15 06:00
date=2016/04/15 06:00

I am a bit confused why the snippet above does not loop through the two nodes. I am also looking for suggestions on how to also "echo out" the name attribute so as to have output that looks like this:

received    date=2015/12/18 00:00
accepted    date=2016/03/31 00:00
aheadofprint    date=2016/04/14 00:00
entrez      date=2016/04/15 06:00
pubmed      date=2016/04/15 06:00
pubmed      date=2016/04/15 06:00

Thanks in advance

Edited by Amaina

2
Contributors
2
Replies
39
Views
1 Year
Discussion Span
Last Post by Amaina
3

It happens because you have to manually move to the next node, you can do like this:

<?php

$file = 'dates.xml';
$xml  = simplexml_load_file($file);

# loop each <date> node
foreach($xml->date as $node) {

    $items = $node->children();

    # loop each date > item
    foreach($items as $item)

        # loop each date > item > item
        foreach($item as $elem)
            $r[] = sprintf('%s %s %s'
                         , $elem->attributes()->Name
                         , $elem->attributes()->Type
                         , $elem);
}

print_r($r);

Will return:

Array
(
    [0] => received Date 2015/12/18 00:00
    [1] => accepted Date 2016/03/31 00:00
    [2] => aheadofprint Date 2016/04/14 00:00
    [3] => entrez Date 2016/04/15 06:00
    [4] => pubmed Date 2016/04/15 06:00
    [5] => medline Date 2016/04/15 06:00
    [6] => epublish Date 2016/05/23 00:00
    [7] => entrez Date 2016/07/12 06:00
    [8] => pubmed Date 2016/07/12 06:00
    [9] => medline Date 2016/07/12 06:00
    [10] => pmc-release Date 2017/01/01 00:00
)

To get the attributes, in this case, since $elem will be a SimpleXMLElement object you can use the attributes() method:

Use var_dump() or a debugger like this to see which kind of object you are iterating, for example:

foreach($items as $item)
    sd($item);

Returns:

SimpleXMLElement (2) (
    public @attributes -> array (2) [
        'Name' => string (7) "History"
        'Type' => string (4) "List"
    ]
    public Item -> array (6) [
        string (16) "2015/12/18 00:00"
        string (16) "2016/03/31 00:00"
        string (16) "2016/04/14 00:00"
        string (16) "2016/04/15 06:00"
        string (16) "2016/04/15 06:00"
        string (16) "2016/04/15 06:00"
    ]
)

So you can see the attributes of the main node:

<Item Name="History" Type="List">

And the contents of the children nodes.
By repeating the debug over the following loop:

foreach($item as $elem)
    sd($elem);

You get:

SimpleXMLElement (1) (
    public @attributes -> array (2) [
        'Name' => string (8) "received"
        'Type' => string (4) "Date"
    ]
)

Which are the attributes for the current node. Hope it helps, bye!

Edited by cereal

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.