我正在记录来自 API 调用的错误请求/响应。为了将日志存储在数据库中,我想用 * 替换信用卡号码。
请求 XML 如下所示:
<xml>
<request servicekey="service key" branchcode="branch" language="EN" postalcode="Postal Code" country="CA" email="<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fe9b939f9792be9b869f938e929bd09d9193" rel="noreferrer noopener nofollow">[email protected]</a>">
<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号被替换为*'s
$responseXML 略有不同:
<string xmlns="http://tempuri.org/">
<xml>
<request servicekey="service key" branchcode="branch code" language="EN" postalcode="Postal Code" country="CA" email="<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="67020a060e0b27021f060a170b024904080a" rel="noreferrer noopener nofollow">[email protected]</a>">
<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 :在非对象上调用成员函数 setAttribute()
,它指向包含 $_reqDom->item(0 )->setAttribute('ccnum','*****');
这两个 xml 之间的唯一区别是其中一个包含在字符串节点中,并且有一个表示响应的额外节点。我想我可以解决这个问题(只需拉出响应节点并将其附加到请求 xml 中),但我现在的使命是让这种方式发挥作用。
最佳答案
问题是由于响应 xml 中的命名空间造成的。您必须使用 XPath 选择器注册 rootNamespace。以下代码将起作用:
$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;
关于php - Xpath setAttribute fatal error 调用成员函数setAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14326300/