simplexml_load_file - redundant element with empty

2019-08-30 10:47发布

I converting a XML-File into an Object using simplexml_load_file. I noticed a problem when a redunant element has a empty value.

I think this example make it more understandable:

// XML-File (Just a small excerpt look at "...")
...
<Team uID="t684">
   ...
    <Player loan="" uID="p20388">
       <Name>Manuel Neuer</Name>
       <Position>Goalkeeper</Position>
       <Stat Type="first_name">Manuel</Stat>
       <Stat Type="last_name">Neuer</Stat>
       <Stat Type="middle_name"></Stat>
       <Stat Type="known_name"></Stat>
       <Stat Type="birth_date">1986-03-27</Stat>
       <Stat Type="birth_place"></Stat>
       <Stat Type="first_nationality"></Stat>
       <Stat Type="deceased"></Stat>
       <Stat Type="preferred_foot"></Stat>
       <Stat Type="weight">92</Stat>
       <Stat Type="height">193</Stat>
       <Stat Type="jersey_num">1</Stat>
       <Stat Type="real_position">Goalkeeper</Stat>
       <Stat Type="real_position_side">Unknown</Stat>
       <Stat Type="join_date">2011-07-01</Stat>
       <Stat Type="country">Germany</Stat>
    </Player>
    ...
</Team>
...

// print_r (simplexml_load_file)
...
[Player] => Array
(
    [0] => SimpleXMLElement Object
    (
            [@attributes] => Array
            (
                    [loan] =>
                    [uID] => p20388
            )
            [Name] => Manuel Neuer
            [Position] => Goalkeeper
            [Stat] => Array(
                    [0] => Manuel
                    [1] => Neuer
                    [2] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => middle_name
                            )
                    )
                    [3] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => known_name
                            )
                    )
                    [4] => 1986-03-27
                    [5] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => birth_place
                            )
                    )
                    [6] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => first_nationality
                            )
                    )
                    [7] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => deceased
                            )
                    )
                    [8] => SimpleXMLElement Object
                    (
                            [@attributes] => Array
                            (
                                    [Type] => preferred_foot
                            )
                     )
                    [9] => 92
                    [10] => 193
                    [11] => 1
                    [12] => Goalkeeper
                    [13] => Unknown
                    [14] => 2011-07-01
                    [15] => Germany
               )
)

It would be the best when the "Type"-name were used as Array Key so I don't have to count on the order in the xml file. But at least a empty xml element value should also be a empty value in the array.

e.g.

<Stat Type="middle_name"></Stat>

should be

[2] => 

instead

[2] => SimpleXMLElement Object
(
    [@attributes] => Array
    (
        [Type] => middle_name
    )
)

I can work with these problems by:

  1. Count on steady order in XML (numeric index)
  2. Proof if value is from type SimpleXMLElement to determine if it's empty.

But that doesn't look like a good solution for me.

Am I doing something wrong or any ideas what I can do?

Many thanks

1条回答
成全新的幸福
2楼-- · 2019-08-30 11:23

It's not really clear to me what you're asking for in the end, however if you want to find out if a SimpleXMLElement hast a Node-Value or not, you can make use of the strlen() function in PHP.

It will take the string context of the SimpleXMLElement which is it's node-value (at least for those leaf-nodes you have in your question) and therefore will return 0 when the node is empty and larger than zero if it contains text.

Accessing a children by an attribute value is not supported by SimpleXMLElement out of the box. The Array-Access works as documented to access attributes, not children; See Example #5 Using attributes.

However you can extend SimpleXMLElement to add that functionality, for example to get a children by the Type attribute value:

class MyXMLElement extends SimpleXMLElement
{
    public function byType($value) {
        list($result) = ((array)$this->getByAttribute('Type', $value)) + array(NULL);
        return $result[0];
    }

    public function getByAttribute($attribute, $value) {
        return $this->xpath(sprintf('.//*[@%s = "%s"]', $attribute, $value));
    }
}

This new variant can be used instead of the old one so that you can easily access what you're looking for:

$team = simplexml_load_string($buffer, 'MyXMLElement');

echo "Team ",  $team['uID'], " Player(s):\n";
foreach($team->Player as $i => $player)
{
    printf(" %d. %s %s\n", $i + 1, $player->byType('first_name'), $player->byType('last_name'));
}

This for example with the reduced example you've got in your question making <Team> the root-element outputs:

Team t684 Player(s):
 1. Manuel Neuer

You find accessing a children by attribute value in SimpleXML outline as well in the following question:

Last time I extended SimpleXMLElement on Stackoverflow was in an answer to Displaying 5 latest thumbnails from public flickr api using atom_1 and php.

No, actually turned out that last time I extended SimpleXMLElement on Stackoverflow was explaining exactly the same access by attribute value thing in the question PHP/XML - how to read multible sub's

查看更多
登录 后发表回答