удалить заголовки soap из ответа перед превращением в простой объект xml - PullRequest
0 голосов
/ 19 июня 2020

Я использую Curl для выполнения запроса soap. Теперь похоже, что в заголовках возвращена ошибка, которая не позволяет мне превратить возвращенную строку в простой объект xml с помощью функции simplexml_load_string. Ниже вы можете найти часть ответа, которая не выполняется в простой функции xml:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header><SOAP-SEC:Signature xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><ds:Reference URI="#Body"><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>HV+/cOkUjNCdH5xuiLlGSHVgkUo=</ds:DigestValue></ds:Reference><ds:SignatureValue>MCwCFHXmoMrDUOScwMQ5g76OfxouICjBAhQtGKAorJLUQ0bA0UaKIe1gtmQPgA==</ds:SignatureValue></ds:SignedInfo></ds:Signature></SOAP-SEC:Signature></SOAP-ENV:Header><SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body">

Есть ли способ изолировать содержимое тела soap и анализировать только это часть с simplexml_load_string?

Под запросом curl:

$headers = array(
              "Content-type: text/xml;charset=\"utf-8\"",
              "Accept: text/xml",
              "Cache-Control: no-cache",
              "Pragma: no-cache",
              "Content-length: ".strlen($xml_post_string),
          ); 

          $url = $soapUrl;

          $ch = curl_init();
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

          $response = curl_exec($ch); 
          curl_close($ch);
$xml = simplexml_load_string(html_entity_decode($response), 'SimpleXMLElement', LIBXML_NOCDATA);

        echo $xml->asXML();

        if ($xml === false) {
          echo "Failed to load XML: ";

          foreach(libxml_get_errors() as $error) {
            echo "<br>", $error->message;
          }
        } else {
          var_dump($xml);
        }












Ответы [ 2 ]

1 голос
/ 24 июня 2020

У меня сейчас нет ответа, но сначала вам нужно отделить curl от обработки XML. Вы должны начать с регистрации результатов curl и убедиться, что они вменяемы и соответствуют вашим ожиданиям. Если это так, , тогда переходите к его синтаксическому анализу. curl никогда не должен нарушать / изменять ваши данные каким-либо образом, но сам запрос (заголовки, et c.) может изменить ответ сервера.

Поскольку я не могу проверить ваш сервер, я просто собирается на go от того, что вы предоставили. Я закрыл тег <SOAP-ENV:Body> и преобразовал XML в читаемый, но в остальном он остался нетронутым. Этот код без проблем анализирует XML и затем выдает его точно так, как ожидалось.

$response = 
    
        
            
                
                    
                    
                        
                        HV+/cOkUjNCdH5xuiLlGSHVgkUo=
                    
                    MCwCFHXmoMrDUOScwMQ5g76OfxouICjBAhQtGKAorJLUQ0bA0UaKIe1gtmQPgA==
                
            
        
    
    

TAG;

$xml = simplexml_load_string(html_entity_decode($response), 'SimpleXMLElement', LIBXML_NOCDATA);

echo '';
print_r(htmlspecialchars($xml->asXML()));
echo '
';

Вывод точно такой же, как и ввод, за исключением того, что он включает директиву XML и преобразует тег тела в самозакрывающийся:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <SOAP-ENV:Header>
        <SOAP-SEC:Signature xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12">
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
                    <ds:Reference URI="#Body">
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>HV+/cOkUjNCdH5xuiLlGSHVgkUo=</ds:DigestValue>
                    </ds:Reference>
                    <ds:SignatureValue>MCwCFHXmoMrDUOScwMQ5g76OfxouICjBAhQtGKAorJLUQ0bA0UaKIe1gtmQPgA==</ds:SignatureValue>
                </ds:SignedInfo>
            </ds:Signature>
        </SOAP-SEC:Signature>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body"/>
</SOAP-ENV:Envelope>

Так что используйте это как базовый уровень. Напишите свой ответ curl в текстовый файл, прежде чем делать что-либо еще, а затем прочитайте этот текстовый файл и выполните logi c. Любое преобразование, которое вы применяете к строке XML, также следует регистрировать и сравнивать, чтобы убедиться, что оно делает то, что вы ожидали. При производстве вы бы пропустили это, но это просто помогает во время отладки.

Кроме того, я не совсем уверен, в чем смысл html_entity_decode. Если вы получаете XML (как указано в mime-типе вашего запроса), то к нему не должно применяться никаких управляющих последовательностей, но, возможно, у вас тоже есть исключительный случай.

0 голосов
/ 25 июня 2020

Просто чтобы привести пример XML содержимого, это будет отличаться для любого файла, но просто показывает, как вы можете получить доступ к данным ...

<SOAP-ENV:Body
    xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12"
    SOAP-SEC:id="Body">
        <BodyContent>SomeData</BodyContent>
        <OtherContent>2</OtherContent>
</SOAP-ENV:Body>

Тогда это будет случай использования XPath для найдите тег <SOAP-ENV:Body>

$xml->registerXPathNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
$bodyBlock = $xml->xpath("//SOAP-ENV:Body")[0];

(обратите внимание, что, поскольку xpath() возвращает список совпадений, при использовании [0] используется только первый).

Эта следующая часть зависит от сообщение обрабатывается, но поскольку в приведенном мною примере есть дочерние элементы без префикса пространства имен, вы можете извлечь их, используя ->children(), и это облегчит доступ к содержимому. Основная часть состоит в том, что на данный момент $bodyBlock содержит это ...

<SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body">
        <BodyContent>SomeData</BodyContent>
        <OtherContent>2</OtherContent>
</SOAP-ENV:Body>

Итак, чтобы объединить это в исходный код ...

$xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);

if ($xml === false) {
    echo "Failed to load XML: ";
    
    foreach(libxml_get_errors() as $error) {
        echo "<br>", $error->message;
    }
} else {
    // Search for the Body element (this is in the SOAP-ENV namespace)
    $xml->registerXPathNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
    $bodyBlock = $xml->xpath("//SOAP-ENV:Body")[0];
    
    // If the content does not have a namespace, extract the children from the default namespace
    $body = $bodyBlock->children();
    
    // You can now access the content.
    echo $body->BodyContent.PHP_EOL;
    echo $body->OtherContent;
    
}

, который выводит два значения в теле ....

SomeData
2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...