Reputation: 2924
I'm having some difficulties in changing XML Node values with PHP.
My XML is the following
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessTransaction
xmlns="http://example.com">
<TransactionRequest
xmlns="http://example.com">
<Header>
<RequestType>SALE</RequestType>
<RequestMethod>SYNCHRONOUS</RequestMethod>
<MerchantInfo>
<PosName>kwstasna</PosName>
<PosID>1234</PosID>
</MerchantInfo>
</Header>
</TransactionRequest>
</ProcessTransaction>
</soap:Body>
</soap:Envelope>
And i want to change PosName
and PosID
.
The XML is received from a POST Request.
If i print_r($REQUEST['xml']
I get the values in text.
And what i've tried is the following
$posid = '321';
$posname = 'nakwsta';
$result = $xml->xpath("/soap:Envelope/soap:Body/ProcessTransaction/TransactionRequest/Header/MerchantInfo");
$result[0]->PosID = $posid;
$result[0]->PosName = $posname;
echo $result;
But i get an empty array Array[]
I think my mistake is in the values of <soap:Envelope
for example.
Anyone that had the same issue and find out the way to solve it?
Thanks a lot for your time.
Upvotes: 0
Views: 212
Reputation: 107767
Consider a parameterized XSLT (not unlike parameterized SQL) where PHP passes value to the underlying script with setParameter().
As information, XSLT (sibling to XPath) is a special-purpose language designed to transform XML files. PHP can run XSLT 1.0 scripts with the XSL class. Specifically, below runs the Identity Transform to copy XML as is and then rewrites the PosName and PosID nodes. Default namespace is handled accordingly in top root tag aligned to doc prefix.
XSLT (save as .xsl file, a special well-formed .xml file)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://example.com">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:param name="PosNameParam"/>
<xsl:param name="PosIDParam"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- RE-WRITE PosName NODE -->
<xsl:template match="doc:PosName">
<xsl:copy>
<xsl:value-of select="$PosNameParam"/>
</xsl:copy>
</xsl:template>
<!-- RE-WRITE PosID NODE -->
<xsl:template match="doc:PosID">
<xsl:copy>
<xsl:value-of select="$PosIDParam"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP
$posid = '321';
$posname = 'nakwsta';
// Load XML and XSL
$xml = new DOMDocument;
$xml->load('Input.xml');
$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');
// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Assign values to XSLT parameters
$proc->setParameter('', 'PosNameParam', $posid);
$proc->setParameter('', 'PosIDParam', $posname);
// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
// Output to console
echo $newXML;
// Output to file
file_put_contents('Output.xml', $newXML);
Output
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessTransaction xmlns="http://example.com">
<TransactionRequest>
<Header>
<RequestType>SALE</RequestType>
<RequestMethod>SYNCHRONOUS</RequestMethod>
<MerchantInfo>
<PosName>nakwsta</PosName>
<PosID>321</PosID>
</MerchantInfo>
</Header>
</TransactionRequest>
</ProcessTransaction>
</soap:Body>
</soap:Envelope>
Upvotes: 2
Reputation: 17443
The ProcessTransaction
element (and all of its child nodes) are in the "http://example.com" namespace. If you want to access them using xpath()
, you'll need to register a namespace prefix:
$xml->registerXPathNamespace('ex', 'http://example.com');
You can then use the ex
prefix on all relevant parts of your query
$result = $xml->xpath("/soap:Envelope/soap:Body/ex:ProcessTransaction/ex:TransactionRequest/ex:Header/ex:MerchantInfo");
The rest of your code should function correctly, see https://eval.in/916856
Upvotes: 4