Анализ данных XML из ответа PHP SOAP

Мне удалось получить ответ от API, с которым я работаю, с помощью Брайана Дрисколла, но у меня возникли проблемы с анализом этих XML-данных. Вот скрипт для получения ответа и возвращенных XML-данных:

$clientC = new SoapClient('http://webservice.nada.com/vehicles/vehicle.asmx?wsdl',array('trace' => 1,'exceptions' => 1, 'cache_wsdl' => 0));

$params = new stdClass();
$params->Token = $token;
$params->Period = 1;
$params->VehicleType = "UsedCar";
$params->Vin = '5YFBURHE3FP331896';
$params->Region = 10;
$params->Mileage = 100;

$result = $clientC->getDefaultVehicleAndValueByVin(array('vehicleRequest' => $params));

$xml = htmlspecialchars($clientC->__getLastResponse());

Это возвращает -

<?xml version = "1.0" encoding = "utf-8"?>
    <soap:Envelope xmlns:soap = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <getDefaultVehicleAndValueByVinResponse xmlns = "http://webservice.nada.com/">
                <getDefaultVehicleAndValueByVinResult>
                    <Uid>1182699</Uid>
                    <VehicleYear>2015</VehicleYear>
                    <MakeCode>47</MakeCode>
               </getDefaultVehicleAndValueByVinResult> 
           </getDefaultVehicleAndValueByVinResponse>
      </soap:Body>
    </soap:Envelope>

Я хотел бы либо проанализировать XML, либо получить что-то вроде

$vehicle_year = $xml->VehicleYear;

Я пытался -

$xml = htmlspecialchars($clientC->__getLastResponse());

$response = strtr($xml, ['</soap:' => '</', '<soap:' => '<']);
$output = json_decode(json_encode(simplexml_load_string($response)));
var_dump($output->Body->getHighVehicleAndValueByVinResponse->VehicleYear);

Но возвращает NULL

Почему вы пытаетесь обрабатывать xml как json? PHP имеет несколько расширений xml. Взгляните на них

kuh-chan 26.03.2019 20:34

Спасибо, я просто лучше знаком с JSON, не особо использовал XML.

Ryan D 26.03.2019 20:34

Кстати, разве htmlspecialchars не уничтожает ваш xml, заменяя < и >?

kuh-chan 26.03.2019 20:39

@kuh-chan да, ты прав, удалить это было необходимо!

Ryan D 26.03.2019 20:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
1 944
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это обычная проблема наличия различных пространств имен, по которым вам нужно перемещаться. Корневой узел определяет xmlns:soap, поэтому вы можете использовать его без каких-либо действий, поэтому XPath использует //soap:Body/* для поиска элемента внутри тега body, поскольку xpath() возвращает список совпадающих узлов, используйте [0], чтобы просто выбрать единственный из них.

Поскольку все данные тела находятся в пространстве имен по умолчанию (определенном как xmlns = "http://webservice.nada.com/"), вы можете извлечь их все, используя $data->children("http://webservice.nada.com/"). Теперь это позволяет вам использовать стандартную нотацию объектов для доступа к значениям.

Следует отметить, что хотя echo автоматически преобразует его в строку, если вы используете эти значения в другом месте — вам может потребоваться преобразовать его с помощью (string), поскольку элемент на самом деле является SimpleXMLElement.

$data = <<< XML
<?xml version = "1.0" encoding = "utf-8"?>
<soap:Envelope xmlns:soap = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <getDefaultVehicleAndValueByVinResponse xmlns = "http://webservice.nada.com/">
            <getDefaultVehicleAndValueByVinResult>
            <Uid>1182699</Uid>
            <VehicleYear>2015</VehicleYear>
            <MakeCode>47</MakeCode>
            </getDefaultVehicleAndValueByVinResult> 
       </getDefaultVehicleAndValueByVinResponse>
    </soap:Body>
</soap:Envelope>
XML;

$xml = simplexml_load_string($data);
$data = $xml->xpath("//soap:Body/*")[0];
$details = $data->children("http://webservice.nada.com/");
echo (string)$details->getDefaultVehicleAndValueByVinResult->VehicleYear;

Большое спасибо за прекрасное объяснение! Это огромная помощь, ура, приятель!

Ryan D 26.03.2019 20:41

Другие вопросы по теме