1

I'm trying to pull information from multiple nested attributes (maybe wrong terminology).

XML String:

<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="2">
  <currentTime>2013-10-01 18:00:01</currentTime>
  <result>
    <rowset name="members" key="characterID" columns="characterID, name">
      <row characterID="2234" name="Bob">
        <rowset name="roles" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRoles" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="titles" key="titleID" columns="titleID,titleName">
          <row titleID="256" titleName="Tiger" />
        </rowset>
      </row>
      <row characterID="555" name="John">
        <rowset name="roles" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRoles" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="titles" key="titleID" columns="titleID,titleName">
          <row titleID="16" titleName="R &amp; D" />
          <row titleID="64" titleName="Miner" />
          <row titleID="256" titleName="Tiger" />
          <row titleID="16384" titleName="POS Manager" />
        </rowset>
      </row>
    </rowset>
  </result>
  <cachedUntil>2013-10-01 18:57:01</cachedUntil>
</eveapi>

Here's my PHP todate:

$simpleXML = simplexml_load_string($xml); // Load XML string data into the simplexml object parser

foreach ($simpleXML->result->rowset->row as $row) {
    $name = $row->attributes()->name;
    $characterID = $row->attributes()->characterID;

    foreach ($row->rowset as $value) {
        $titleName .= $value->row->attributes()->titleName.',';
    }

    echo $Name.'<br>';
    echo $titleName.'<br>';
}

What I'd like to output for each name would be:

Bob

Tiger

John

R&D,Miner,Tiger,POS Manager

2 Answers 2

2

You're looking to get query specific data from the XML Tree. This is most easily done with Xpath which is also supported by SimpleXMLElement:

foreach ($rows as $row) {
    $titleNames = $row->xpath('*[@name="titles"]/row/@titleName');
    echo $row['name'], ': ', implode(', ', $titleNames), "\n";
}

This is running an xpath query on each main row element on those child-elements which have titles as name attribute and then getting all their row titleName attribute nodes which are - when used in string context like with implode turned into their attribute value as string.

The output of that example:

Bob: Tiger
John: R & D, Miner, Tiger, POS Manager

The code-example (without your data):

$xml = simplexml_load_string($xml); 

$rows = $xml->result->rowset->row;

foreach ($rows as $row) {
    $titleNames = $row->xpath('*[@name="titles"]/row/@titleName');
    echo $row['name'], ': ', implode(', ', $titleNames), "\n";
}

And the online demo: https://eval.in/52408

Xpath queries work remarkable well for the nested structures XML documents often come with. If you want to express the same in PHP code, you would have much more nested loops.

See as well:

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

Comments

1

It can be difficult to work out how to access elements of SimpleXML sometimes.

You need something like this:-

foreach ($simpleXML->result->rowset->row as $row) {
    $titles = [];
    $name = $row['name']->__toString();
    foreach($row as $attrib){
        if($attrib['name']->__toString() === 'titles'){
            foreach($attrib as $title){
                $titles[] = $title['titleName']->__toString();
            }
        }
    }
    echo $name . ' : ' . implode(' - ', $titles) . "<br/>\n";
}

See it working.

Comments

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.