I’m logging error requests/responses from an API call. In order to store the logs in the DB, I’d like to replace the credit card numbers with *’s.
The request XML looks like this:
<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>
From here I simply grab the payment node and the ccnum attribute to edit it (the xml is saved as $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();
It works as expected, the CC number in the xml is replaced with *’s
The $responseXML is a touch different:
<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>
Same idea as before, I run a very similar piece of PHP code:
$_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();
But when I run this I get Fatal error: Call to a member function setAttribute() on a non-object that points to the line that contains $_reqDom->item(0)->setAttribute('ccnum','*****');
The only difference between the 2 xml’s is one is contained within a string node and has an extra node that says response. I suppose I could do a work around (just pull out the response node and append it to the request xml), but I’m now at the point where getting this way to work is my mission.
The problem is because of the namespace in the response xml. You’ll have to register the rootNamespace with the XPath selector.The following code will work: