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...
   )
)
6
  • How are you converting it to an array now? Just by casting? Commented Aug 21, 2018 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 <block> has #SUB-PREM# but the second one is missing it. Are you looking for magic or something? Commented Aug 21, 2018 at 16:13
  • @iainn i have updated the question. I should have included this :) Commented Aug 21, 2018 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 Commented Aug 21, 2018 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… Commented Aug 21, 2018 at 16:17

1 Answer 1

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

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

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.