Search code examples
phpjsonxmlphp-curl

PHP - JSON encode output contains only 1 XML entry instead of multiple


UPDATE:

Previous post: link

Ok so I got the code working perfectly for 1 customer. Now i ran into another problem if i wanna recieve multiple customers as JSON output , how would i do that ?

I've created a second entry under accounts with status C and modified the code parts i've recieved so far to basically output name/email/... from all accounts with status C. However im only recieving the first one it sees. Probably made a mistake somewhere

$document = new DOMDocument();
$document->loadXML($response);
$xpath = new DOMxpath($document);

$json = [];
foreach ($xpath->evaluate('(/eExact/Accounts)') as $account) {
    $json['email'] = $xpath->evaluate('string(Account[@status="C"]/Email)', $account);
    
    $json['first_name'] = $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/FirstName)', $account);
    $json['last_name'] = $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/LastName)', $account);
    $json['billing'] = [
      'first_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/FirstName)', $account),
      'last_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/LastName)', $account),
      'postcode'=> $xpath->evaluate('string(Account[@status="C"]/Address[@default="1"]/PostalCode)', $account),
    ];

    // ...
}

$customer = json_encode($json, JSON_PRETTY_PRINT);
echo $customer; 

Output:

{
    "email": "example1@example1.com",
    "first_name": "John",
    "last_name": "Doe",
    "billing": {
        "first_name": "John",
        "last_name": "Doe",
        "postcode": "10000"
    }
}[Finished in 0.4s]

What i actually would want is something like this: [or in other words all status C accounts ]

 {
        "email": "example1@example1.com",
        "first_name": "John",
        "last_name": "Doe",
        "billing": {
            "first_name": "John",
            "last_name": "Doe",
            "postcode": "10000"
        }
 {
        "email": "example2@example2.com",
        "first_name": "Steve",
        "last_name": "Doe",
        "billing": {
            "first_name": "Steve",
            "last_name": "Doe",
            "postcode": "20000"
        }

Solution

  • You are overwriting your $json array keys with each iteration. You made it a one-dimensional array and what you need is a multidimensional array (where each element is another array):

    foreach ($xpath->evaluate('(/eExact/Accounts)') as $account) {
        $json[] = [
            'email' => $xpath->evaluate('string(Account[@status="C"]/Email)', $account),
            'first_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/FirstName)', $account),
            'last_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/LastName)', $account),
            'billing' => [
                'first_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/FirstName)', $account),
                'last_name' => $xpath->evaluate('string(Account[@status="C"]/Contact[@default="1"]/LastName)', $account),
                'postcode'=> $xpath->evaluate('string(Account[@status="C"]/Address[@default="1"]/PostalCode)', $account),
            ],
        ];
    }
    

    The key here is $json[] = ... - this tells PHP to create a new element in the array and assign it the value that follows.