1

I'm currently trying to create a generic PHP class to enable retrieval of XML data. The data all comes in a similar format but will have different element names and sometimes there may be more elements. Example xml:

One feed may show this:

<GroupData>
   <Table diff:id="1">
      <Code>1</Code>
      <Name>Red</Name>
      <Type>X</Type>
   </Table>
   <Table diff:id="2">
      <Code>2</Code>
      <Name>Yellow</Name>
      <Type>Y</Type>
   </Table>
</GroupData>

Another feed might show:

<GroupData>
   <Table diff:id="1">
      <Code>1</Code>
      <Name>Red</Name>
   </Table>
   <Table diff:id="2">
      <Code>2</Code>
      <Name>Yellow</Name>
   </Table>
</GroupData> 

My PHP looks like this:

$dom = DOMDocument::loadXML($xml);

$node_list = $dom->getElementsByTagName('Table');

for($i=0; $i < $node_list->length; $i++) {

     echo $node_list->item($i)->nodeValue;

}

This brings back data, but it's not quite what I'm looking for. I'd like it splitting out so I can see the element name and the element value and then create an array out of the data for future use. Is there a way of doing this without using "getElementsByTagName" which is what I have used before to get XML? I know each feed I receive will have Table so I can loop through this each time. Thanks for the help.

1

1 Answer 1

2

getElementsByTagName() looks appropriate. The code should look like this:

$doc = new DOMDocument();
$doc->loadXML($xml);

$tables = $doc->getElementsByTagName('Table');
$data = array();
foreach($tables as $table) {
    $id = $table->getAttribute('id');
    $record = array();
    foreach($table->childNodes as $child) {
        if($child->nodeType === XML_ELEMENT_NODE) {
            $record[$child->nodeName] = $child->nodeValue; 
        }   
    }   
    $data[$id] = $record;
}

var_dump($data);

The code creates a multidimensional array where the first dimension's index are the table id's and the second dimension are arrays having key/value pairs from the XML. I've simplified it a little bit and dropped the diff: namespace prefixes for this example as they are invalid (not registered) in the snippets you've shown. In the real world code you will need getAttributeNS('diff', 'id') instead.

This will give you:

array(2) {
  [1] =>
  array(3) {
    'Code' =>
    string(1) "1"
    'Name' =>
    string(3) "Red"
    'Type' =>
    string(1) "X"
  }
  [2] =>
  array(3) {
    'Code' =>
    string(1) "2"
    'Name' =>
    string(6) "Yellow"
    'Type' =>
    string(1) "Y"
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

you are welcome! :) take also care about what did I said about that namespace diff:

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.