0

OK、SOAPClientに電話をかけてもらいます。__getLastResponse()を使用すると、XMLに次のような行が表示されます。

<Discount xsi:type="ProgressivePromotion" from="2013-05-05T00:00:00" to="2013-05-14T00:00:00" type="Percent" value="20" name="Special Deal"/>

ただし、SOAPClientクラスの関数はオブジェクトを返します。

PHPクラスの呼び出しのコードは次のとおりです。

function SearchHotels($parameters ){
$funcRet = null;
try {
    $funcRet = $this->client->SearchHotels($parameters);
} catch ( Exception $e ) {
    echo "(SearchHotels) SOAP Error:\n-------------------------------------\n" . $e->getMessage () . "\n\n";
    echo "(SearchHotels) Request:\n-------------------------------------\n" . $this->client->__getLastRequest() . "\n\n";
    echo "(SearchHotels) Response:\n-------------------------------------\n" . $this->client->__getLastResponse() . "\n\n";
}
return $funcRet; 
}

返されたオブジェクトを使用すると、Discount要素から次の属性にアクセスできます。

タイプ:ProgressivePromotion
from:2013-05-05T00:00:00
to:2013-05-14T00:00:00
value:20
name:Special Deal

しかし、type="Percent"にアクセスできません

SOAPClientはxsi:typeのxsi名前空間を無視し、その属性をtypeとして格納しているようです。

では、xsi:type AND typeにアクセスして、割引がパーセントまたは金額、あるいはその他のタイプであるかどうかを確認するにはどうすればよいですか?

ところで、SOAP応答の上部に、xsiが何であるかを宣言しているものは何も表示されません。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <SearchHotelsResponse xmlns="http://tourico.com/webservices/hotelv3">
            <SearchHotelsResult>
                <Info xmlns="http://schemas.tourico.com/webservices/hotelv3" version="9.71" culture="en-US" serverTime="2013-02-06T14:49:58.3500117-05:00"/>
                   <HotelList xmlns="http://schemas.tourico.com/webservices/hotelv3">

編集

返されたオブジェクトをvar_dumpすると、次のようになります。

stdClass Object
(
[SearchHotelsResult] => stdClass Object
    (
        [Info] => stdClass Object
            (
                [version] => 9.71
                [culture] => en-US
                [serverTime] => 2013-02-06T15:17:59.8445748-05:00
            )

        [HotelList] => stdClass Object
            (
                [Hotel] => Array
                    (
                        [0] => stdClass Object
                            [RoomTypes] => stdClass Object
                                    (
                                        [RoomType] => Array
                                            (
                                                [0] => stdClass Object
                                                    (
                                                       [Discount] => stdClass Object
                                                            (
                                                                [from] => 2013-05-05T00:00:00
                                                                [to] => 2013-05-14T00:00:00
                                                                [type] => ProgressivePromotion
                                                                [value] => 20
                                                                [name] => Special Deal
                                                            )

type ="Amount"を失った方法をご覧ください。

して割引を呼び出すことはできません

echo $result->SearchHotelsResult->HotelList->Hotel[0]->RoomTypes->RoomType[0]->Discounts->type;

私が得るので

Undefined property: stdClass::$Discounts  Notice: Trying to get property of non-object

そこで、オブジェクト全体を巨大な多次元配列に変換し、その方法でアクセスします。とにかく、type="Amount"はプルされていません。

4

2 に答える 2

1

私はこの方法で問題を修正しました。

<?php
class fixSoapClient extends SoapClient{
    function __doRequest($request, $location, $action, $version, $one_way = 0) {
        $result = parent::__doRequest($request, $location, $action, $version);
        $str = preg_replace('#<Discount xsi:type="ProgressivePromotion"(.+)type="(.+)"(.+)name="(.+)"/>#isU', 
                '<Discount xsi:type="ProgressivePromotion"$1type="wath ever"$3name="$2"/>', $result);
        return $str;
    }   
}

name属性に割引タイプがあります。したがって、インスタンス化する代わりに、インスタンス化SoapClientする必要がありますfixSoapClient

于 2013-02-07T15:23:11.380 に答える
0

名前空間対応のXMLパーサーを使用して応答を解析しているようですが、パーサーの名前空間サポートがオンになっていません。これにより、2つのルールが衝突します。

  1. 名前空間を使用してXMLドキュメントを解析する場合、すべての要素と属性は展開された名前で参照されます。拡張名は、名前空間URIと要素/属性のローカル名で構成されます。パーサーが名前空間を認識していない場合、名前のURI部分は失われます。したがって、名前空間サポートを備えた一部のパーサーは、名前空間サポートがオンになっていない場合、名前空間プレフィックスも削除します。
  2. 要素に同じ(拡張された)名前の2つの属性を含めることはできません。このような場合、他の1つの属性が失われます。通常、名前空間を認識するXMLパーサーは、これら2つのtype属性を{http://www.w3.org/2001/XMLSchema-instance}typetypeJames Clark表記を使用して)およびとして認識します。名前空間を認識しないパーサーは、属性名xsi:typeとを返す必要がありtypeます。これらの場合、名前の衝突はなく、すべてが正常に機能するはずです。

:コロンが名前空間プレフィックス区切り文字として機能することをパーサーが認識しているが、パーサーが名前空間を使用していないため、区切り文字と名前空間プレフィックスを削除すると、問題が発生します。次に、これらの属性の両方が名前を取得typeし、属性名の一意性ルールのために、これらの他の1つが失われる/上書きされます。

解決策:パーサーの名前空間サポートをオンに設定するか、別のより機能的なパーサーに切り替えます。XMLファイルの解析方法に関する情報で質問を更新すると、誰かがより具体的な回答を提供できることを願っています。

于 2013-02-13T00:36:06.493 に答える