2

API 呼び出しからのエラー要求/応答をログに記録しています。ログを DB に保存するために、クレジット カード番号を * に置き換えたいと考えています。

リクエスト XML は次のようになります。

<xml>
    <request servicekey="service key" branchcode="branch" language="EN" postalcode="Postal Code" country="CA" email="email@example.com">
        <paxes>
            <pax id="1" birthdate="19790215" firstname="John" lastname="Smith" />
            <pax id="2" birthdate="19800828" firstname="Jane" lastname="Smith" />
        </paxes>
        <plans>
            <plan code="Plan Code" >
                <paxes>
                    <pax id="1" sumins="1200.00" />
                    <pax id="2" sumins="1480.31" />
                </paxes>
            </plan>
        </plans>
        <payments>
            <payment amount="246.24" type="VI" ccnum="4111111111111111" ccexp="0711" ccname="John Smith" />
        </payments>
    </request>
</xml>

ここから、支払いノードと ccnum 属性を取得して編集します (xml は $requestXML として保存されます)。

$_req = new DOMDocument();
$_req->loadXML($requestXML);
$_xpathReq = new DOMXPath($_req);
$_reqDom = $_xpathReq->query("/xml/request/payments/payment");
$_reqDom->item(0)->setAttribute('ccnum','*****');
$requestXML = $_req->saveXML();    

期待どおりに動作し、xml の CC 番号は * に置き換えられます

$responseXML は少し異なります。

<string xmlns="http://tempuri.org/">
    <xml>
        <request servicekey="service key" branchcode="branch code" language="EN" postalcode="Postal Code" country="CA" email="email@example.com">
            <paxes>
                <pax id="1" birthdate="19790215" firstname="John" lastname="Smith" />
                <pax id="2" birthdate="19800828" firstname="Jane" lastname="Smith" />
            </paxes>
            <plans>
                <plan code="Plan Code">
                    <paxes>
                        <pax id="1" sumins="1200.00" />
                        <pax id="2" sumins="1480.31" />
                    </paxes>
                </plan>
            </plans>
            <payments>
                <payment amount="246.24" type="VI" ccnum="4111111111111111" ccexp="0711" ccname="John Smith" />
            </payments>
        </request>
        <response>
            <errors>
                <error>Purchase Card Processing was not approved [-1]:Cancelled: null | CARD: **** | Exp: 1407 | Amount: $246.24</error>
            </errors>
        </response>
    </xml>
</string>

前と同じ考え方で、非常によく似た PHP コードを実行します。

$_req = new DOMDocument();
    $_req->loadXML($responseXML);
    $_xpathReq = new DOMXPath($_req);
    $_reqDom = $_xpathReq->query("/string/xml/request/payments/payment");
    $_reqDom->item(0)->setAttribute('ccnum','*****');
    $responseXML = $_req->saveXML(); 

しかし、これを実行すると、次Fatal error: Call to a member function setAttribute() on a non-objectを含む行へのポイントが取得されます$_reqDom->item(0)->setAttribute('ccnum','*****');

2 つの xml の唯一の違いは、1 つが文字列ノード内に含まれており、応答を示す余分なノードがあることです。回避策を講じることができると思います (応答ノードを取り出して、それを要求 xml に追加するだけです) が、この方法で機能させることが私の使命になっています。

4

3 に答える 3

2

問題は、応答 xml の名前空間が原因です。rootNamespace を XPath セレクターに登録する必要があります。次のコードが機能します。

$response = new DOMDocument();
$response->loadXML($responseXml);
$selector = new DOMXPath($response);

// get the root namespace
$rootNamespace = $response->lookupNamespaceUri(
    $response->namespaceURI
);
// and register it with $selector. I'm using 'x' as the prefix
// you are free to use a different prefix
$selector->registerNamespace('x', $rootNamespace);

// You won't need to specify the whole path. You could just grab 
// all payment node regardless of their location in the xml tree
$result = $selector->query('//x:payment');
foreach($result as $node) {
    $node->setAttribute('ccnum', '*****');
}

$responseXml = $response->saveXML();
echo $responseXml;
于 2013-01-14T21:21:59.947 に答える
1

タグには名前空間が含まれているため、その<string>名前空間を DOMXPath に登録する必要があります。

$_req = new DOMDocument();
$_req->loadXML($responseXML);
$_xpathReq = new DOMXPath($_req);

$_xmlns = $_req->lookupNamespaceUri(NULL); 
$_xpathReq->registerNamespace('x', $_xmlns); 

$_reqDom = $_xpathReq->query("//x:xml/x:request/x:payments/x:payment");
$_reqDom->item(0)->setAttribute('ccnum','*****');
$responseXML = $_req->saveXML(); 
于 2013-01-14T21:21:49.600 に答える
0

XMLに次のように定義されたいくつかの名前空間があるという同様の問題がありました。

<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom" 
        xmlns:dc="http://purl.org/dc/elements/1.1/" 
        xmlns:dcterms="http://purl.org/dc/terms/" 
        xmlns:media="http://search.yahoo.com/mrss/" 
        xmlns:xhtml="http://www.w3.org/1999/xhtml">

DOMXPathこれにより、クエリを実行できなくなりました。

次の方法で xml をインポートすることで修正されました。

libxml_use_internal_errors(true);
$doc->loadHTML($rawXml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NSCLEAN);
libxml_use_internal_errors(false);

これが誰かに役立つことを願っています。これで髪が抜けた…

于 2016-06-08T19:58:46.070 に答える