Получить значение атрибута из Soap Ответ PHP - PullRequest
1 голос
/ 12 марта 2020

Я получаю soap ответ, как и ожидалось, а затем преобразую в массив. Вот мой код:

$response = $client->__getLastResponse();
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody')[0];
$array = json_decode( str_replace('@', '', json_encode((array)$body)), TRUE); 
print_r($array);

вот вывод:

Array ( 
[GetCompanyCodeResponse] => Array ( 
    [GetCompanyCodeResult] => Array ( 
        [Customers] => Array ( 
            [Customer] => Array ( 
                [attributes] => Array ( 
                    [CustomerNo] => 103987 
                    [CustomerName] => epds api testers Inc 
                    [ContactId] => 219196 
                ) 
            ) 
        ) 
    ) 
) 

Как мне отобразить ContactId? Я пробовал следующее:

$att = $array->attributes();
$array->attributes()->{'ContactId'};
print_r($array);

Я получаю следующую ошибку:

Fatal error: Uncaught Error: Call to a member function attributes() on array 

Также пробовал:

$array->Customer['CustomerId'];

Я получаю следующую ошибку:

Notice: Trying to get property 'Customer' of non-object

Ожидается получение 219196

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Вы последовали очень плохому совету о том, как разобрать XML, и полностью отбросили функциональность Simple XML.

В частности, причина, по которой вы не можете запустить attributes() Метод заключается в том, что вы преобразовали объект Simple XML в простой массив с помощью этого уродливого хака:

$array = json_decode( str_replace('@', '', json_encode((array)$body)), TRUE); 

Чтобы использовать Simple XML по назначению авторов, я предлагаю вам прочитать:

Так как вы не вставили фактический XML в вопрос, я собираюсь предположить, что это выглядит так:

<?xml version = "1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
   <soap:Body xmlns="http://www.example.org/companyInfo">
      <GetCompanyCodeResponse>
         <GetCompanyCodeResult>
            <Customers>
                <Customer CustomerNo="103987" CustomerName="epds api testers Inc" ContactId="219196" />
            </Customers>
         </GetCompanyCodeResult>
      </GetCompanyCodeResponse>
   </soap:Body>
</soap:Envelope>

Если это в $response, мы не нужно сделать какие-то странности с str_replace или json_encode, мы можем использовать методы, встроенные в Simple XML, для навигации по XML:

$xml = new SimpleXMLElement($response);
// The Body is in the SOAP Envelope namespace
$body = $xml->children('http://www.w3.org/2001/12/soap-envelope')->Body;
// The element inside that is in some other namespace
$innerResponse = $body->children('http://www.example.org/companyInfo')->GetCompanyCodeResponse;
// We need to traverse the XML to get to the node we're interested in
$customer = $innerResponse->GetCompanyCodeResult->Customers->Customer;
// Unprefixed attributes aren't technically in any namespace (an oddity in the XML namespace spec!)
$attributes = $customer->attributes(null);
// Here's the value you were looking for
echo $attributes['ContactId'];

В отличие от вашего предыдущего кода, это выиграло ' t break, если:

  • Сервер начинает использовать другой локальный префикс вместо soap: или добавляет префикс на GetCompanyCodeResponse element
  • Ответ возвращается с более чем одним Customer (->Customer всегда означает то же самое, что и ->Customer[0], первый дочерний элемент с таким именем)
  • Элемент Customer имеет дочерние элементы или текстовое содержимое, а также атрибуты

Он также позволяет использовать другие функции Simple XML, например , с использованием выражения xpath для поиска в document или даже переход на полный DOM API для более сложных операций .

0 голосов
/ 12 марта 2020

Я нашел решение вышеуказанной проблемы. Не уверен, что это самый элегантный способ сделать это, но он возвращает результат, как и ожидалось. Если есть более эффективный способ получения ContactId, я открыт для предложений.

print_r($array['GetCompanyCodeResponse']['GetCompanyCodeResult']
['Customers']['Customer']['attributes']['ContactId']);
...