3

これは私が使用しているコードです:

$doc = // SOAP Response
            $xpath = new DOMXPath($doc);
            $xpath->registerNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
            $xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');

// Response:
            if ($xpath->query('/soap:Envelope/soap:Body/api:get_cdrsResponse')->length < 1)
            {
                throw new EnswitchResponseFaultException();
            }

それはこの例外をスローし続けます私は何を間違っているのですか?

これは私が得ている応答です(Pastebinリンク):

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><get_cdrsResponse 
    xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
<s-gensym3>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abc</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid</bill_type>
</s-gensym3>
4

3 に答える 3

2

XML 名前空間を次のものに登録する必要があります。

$xpath->registerNamespace('api', 'http://www.flatplanetphone.net/Integrics/Enswitch/API');

いいえ

$xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');

応答は次のように返されます。

<get_cdrsResponse xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">

この URL が解決可能かどうかは問題ではなく、文字列が一致するかどうかだけが重要です。

于 2013-03-18T14:06:08.717 に答える
2

序章

どこで取得したかわかりませんが$xpath->registerNamespace('api', 'http://127.0.0.1/Integrics/Enswitch/API');、有効ではありませんnamespace使用できるすべての有効な名前空間を取得してください

$sxe = new SimpleXMLElement($xml);
print_r($sxe->getDocNamespaces(true));

出力

Array
(
    [xsi] => http://www.w3.org/2001/XMLSchema-instance
    [soapenc] => http://schemas.xmlsoap.org/soap/encoding/
    [xsd] => http://www.w3.org/2001/XMLSchema
    [soap] => http://schemas.xmlsoap.org/soap/envelope/
    [] => http://www.flatplanetphone.net/Integrics/Enswitch/API
)

あなたは過去ビンからXML

$xml = '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><get_cdrsResponse 
    xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
<s-gensym3>
<scustomer xsi:type="xsd:string">4458</scustomer>
<recording xsi:type="xsd:string" />
<outgroup_name xsi:type="xsd:string">abc</outgroup_name>
<bill_type xsi:type="xsd:string">prepaid</bill_type>
</s-gensym3>
</get_cdrsResponse>
</soap:Body>
</soap:Envelope>';

解決

$sxe = new SimpleXMLElement($xml);
$sxe->registerXPathNamespace("api", "http://www.flatplanetphone.net/Integrics/Enswitch/API");
$path = $sxe->xpath("//api:s-gensym3");
$info = array_shift($path);

if (!$info)
    throw new Exception("Invalid Response");

echo $info->scustomer, PHP_EOL;
echo $info->recording, PHP_EOL;
echo $info->outgroup_name, PHP_EOL;
echo $info->bill_type, PHP_EOL;

出力

4458

abc
prepaid

ライブデモを見る

======================================

アップデート

======================================

複数の子を扱う場合は、名前空間を無視してSimpleXMLElement::childrenを使用できます

$xml = '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <get_cdrsResponse xmlns="http://www.flatplanetphone.net/Integrics/Enswitch/API">
            <s-gensym3>
                <scustomer xsi:type="xsd:string">4458</scustomer>
                <recording xsi:type="xsd:string" />
                <outgroup_name xsi:type="xsd:string">abc</outgroup_name>
                <bill_type xsi:type="xsd:string">prepaid14</bill_type>
            </s-gensym3>
            <s-gensym5>
                <scustomer xsi:type="xsd:string">4458</scustomer>
                <recording xsi:type="xsd:string" />
                <outgroup_name xsi:type="xsd:string">abcd</outgroup_name>
                <bill_type xsi:type="xsd:string">prepaid</bill_type>
            </s-gensym5>
            <s-gensym7>
                <scustomer xsi:type="xsd:string">4458</scustomer>
                <recording xsi:type="xsd:string" />
                <outgroup_name xsi:type="xsd:string">abce</outgroup_name>
                <bill_type xsi:type="xsd:string">prepaid13</bill_type>
            </s-gensym7>
            <s-gensym11>
                <scustomer xsi:type="xsd:string">4458</scustomer>
                <recording xsi:type="xsd:string" />
                <outgroup_name xsi:type="xsd:string">abcf</outgroup_name>
                <bill_type xsi:type="xsd:string">prepaid12</bill_type>
            </s-gensym11>
        </get_cdrsResponse>
    </soap:Body>
</soap:Envelope>';

$sxe = new SimpleXMLElement($xml);
$response = $sxe->children('soap', true)->Body->children()->get_cdrsResponse;

foreach ( $response->children() as $gensym ) {
    echo $gensym->scustomer, PHP_EOL;
    echo $gensym->recording, PHP_EOL;
    echo $gensym->outgroup_name, PHP_EOL;
    echo $gensym->bill_type, PHP_EOL;
    echo PHP_EOL;
    echo PHP_EOL;
}
于 2013-03-18T19:12:21.560 に答える
1

私があなたのラインを交換するとき

if ($xpath->query('/soap:Envelope/soap:Body/api:get_cdrsResponse')->length < 1)

と:

if ($xpath->query('/soap:Envelope/soap:Body/get_cdrsResponse')->length < 1)

get_cdrsResponse から「xmlns」の部分を削除すると機能します。問題はそのapi:部分にあります。get_cdrsResponse の xmlns が 404 ( http://www.flatplanetphone.net/Integrics/Enswitch/API ) を返すことに気付いたので、それを修正することをお勧めします。

于 2013-03-14T15:37:57.043 に答える