0

Ok so i have a problem where i am pulling data base from an API and the structure is returned as below:

<Response id="responceidgoeshere">
  <block name="addresses">
    <block>
      <a name="building" format="text">#NAME/NUM#</a>
      <a name="sub-premise" format="text">#SUB-PREM#</a>
      <a name="street" format="text">#STREET#</a>
      <a name="locality" format="text">#LOCAL#</a>
      <a name="city" format="text">#CITY#</a>
      <a name="postcode" format="text">#POSTCODE#</a>
      <a name="ref" format="text">#REF#</a>
      <a name="csscode" format="text">#CSS#</a>
    </block>
    <block>
      <a name="building" format="text">#NAME/NUM#</a>
      <a name="street" format="text">#STREET#</a>
      <a name="locality" format="text">#LOCAL#</a>
      <a name="city" format="text">#CITY#</a>
      <a name="postcode" format="text">#POSTCODE#</a>
      <a name="ref" format="text"/>
      <a name="csscode" format="text"/>
    </block>
    </block>
</Response>

However, you can see the data changes slightly between results depending on the address. When i use simpleXML to convert to PHP array i end up with the following:

EDIT: including conversion method:

$xml=simplexml_load_string($result, "SimpleXMLElement", LIBXML_NOCDATA);
$json=json_encode($xml);
$array=json_decode($json,TRUE);

Result:

[0] => Array
    (
        [a] => Array
            (
                [0] => #NAME/NUM#
                [1] => #SUB-PREM#
                [2] => #STREET#
                [3] => #LOCAL#
                [4] => #CITY#
                [5] => #POSTCODE#
                [6] => #REF#
                [7] => #CSS#
            )
    [1] => Array
    (
        [a] => Array
            (
                [0] => #NAME/NUM#
                [1] => #STREET#
                [2] => #LOCAL#
                [3] => #CITY#
                [4] => #POSTCODE#
                [5] => #REF#
                [6] => #CSS#
            )

I ideally need a way to create a PHP array with the "name" attr as the key. Does anyone know the best way to do this as the standard simpleXML is too inconsitent for what i need as there wont always be a sub premice element and sometimes there will be a county element too.

EDIT: Example of desired structure:

[0]=array
(
   [a]=array
   (
       ['building'] => #NAME/NUM#,
       ['sub-premise'] => #SUB-PREM#,
       ['street'] => #STREET#,
       etc...
   )
)
JamieP
  • 25
  • 7
  • How are you converting it to an array now? Just by casting? – iainn Aug 21 '18 at 16:11
  • I don't get it, what are you trying to achieve? Please post a sample of the desired result array. Your resulting array reflects the XML which was given to it. The first `` has `#SUB-PREM#` but the second one is missing it. Are you looking for magic or something? – MonkeyZeus Aug 21 '18 at 16:13
  • @iainn i have updated the question. I should have included this :) – JamieP Aug 21 '18 at 16:14
  • @MonkeyZeus This is why i need to use the name="" element as the data is incosistent on the returned feed i will update with an example of what i need in the question – JamieP Aug 21 '18 at 16:15
  • 1
    You'll have to loop through the SimpleXML object/array and create your own data in the format that you need, instead of just depending on the default conversion behaviour… – deceze Aug 21 '18 at 16:17
  • What @deceze said; there is no free lunch. Check out https://stackoverflow.com/q/6578832 for ideas on what you can try coding yourself. – MonkeyZeus Aug 21 '18 at 16:21

1 Answers1

2

Converting a SimpleXMLElement object to an array using either json_decode/encode or casting with (array) is almost always going to end up losing data (especially XML attributes). You'll find it a lot easier trying to access them using their native API rather than trying to blindly convert them into something else.

What you need to do can be achieved quite easily by looping over the elements, and building an array indexed by the name attributes:

$result = [];

foreach ($sxml->block->block as $block) {
    $row = [];

    foreach ($block->a as $a) {
        $row[(string) $a['name']] = (string) $a;
    }

    $result[] = $row;
}

See https://3v4l.org/mBoFO

iainn
  • 16,826
  • 9
  • 33
  • 40