Change XML node element value in PHP and save file
You can use XPath to find the specific element. SimpleXMLElement->xpath() returns an array of (matching) SimpleXMLElement objects, i.e. you can access and change the data of each element just like you would in "your" foreach loop.
<?php
// $testimonials = simplexml_load_file('test.xml');
$testimonials = new SimpleXMLElement('<testimonials>
<testimonial id="4c050652f0c3e">
<nimi>John</nimi>
<email>test@test.com</email>
<text>Some text</text>
<active>1</active>
</testimonial>
<testimonial id="4c05085e1cd4f">
<name>ats</name>
<email>some@test.ee</email>
<text>Great site!</text>
<active>0</active>
</testimonial>
</testimonials>');
// there can be only one item with a specific id, but foreach doesn't hurt here
foreach( $testimonials->xpath("testimonial[@id='4c05085e1cd4f']") as $t ) {
$t->name = 'LALALA';
}
echo $testimonials->asXML();
// $testimonials->asXML('test.xml');
prints<?xml version="1.0"?>
<testimonials>
<testimonial id="4c050652f0c3e">
<nimi>John</nimi>
<email>test@test.com</email>
<text>Some text</text>
<active>1</active>
</testimonial>
<testimonial id="4c05085e1cd4f">
<name>LALALA</name>
<email>some@test.ee</email>
<text>Great site!</text>
<active>0</active>
</testimonial>
</testimonials>
Updating XML node with PHP
You're not accessing the right node. In your example, $xml
holds the root node <info/>
. Here's a great tip: always name the variable that holds your XML document after its root node, it will prevent such confusion.
Also, as Ward Muylaert pointed out, you need to save the file.
Here's the corrected example:
// load the document
// the root node is <info/> so we load it into $info
$info = simplexml_load_file('test.xml');
// update
$info->user->name->nameCoordinate->xName = $xPostName;
$info->user->name->nameCoordinate->yName = $yPostName;
// save the updated document
$info->asXML('test.xml');
Modification and replacement of nodes in xml file
Document manipulations are much easier with DOM because each part is represented by a node object that knows about its context. For your case you can build up an index of nodes grouped by a key generated from the OPBEL and XBLNR values. Then merge the grouped nodes.
$document = new DOMDocument();
$document->loadXML(getXML());
$xpath = new DOMXPath($document);
// iterate all header elements (do not merge items from different headers)
foreach ($xpath->evaluate('//Z1COLL_HEADER ') as $header) {
$groups = [];
// iterate the items
foreach ($xpath->evaluate('Z1COLL_ITEM', $header) as $item) {
// combine keys into a single string
$groupKey = $xpath->evaluate('concat(OPBEL, "|", XBLNR)', $item);
if (!isset($groups[$groupKey])) {
$groups[$groupKey] = [];
}
// add the current item to a group defined by the generated key
$groups[$groupKey][] = $item;
}
// now filter for groups with multiple items
$groups = array_filter($groups, function($group) { return count($group) > 1; });
// iterate the groups with multiple items
foreach ($groups as $group) {
// extract the first item node from the array
$firstItem = array_shift($group);
// iterate the other items of the group
foreach ($group as $item) {
$merges = ['INITAMNT', 'PAYAMNT', 'WRTOFFAMNT', 'OPENAMNT', 'INVAMNT'];
// iterate the child node names to merge
foreach ($merges as $merge) {
// get the node of the first item
$target = $xpath->evaluate($merge, $firstItem)->item(0);
// get the node of the current item
$source = $xpath->evaluate($merge, $item)->item(0);
// if here are both
if ($target && $source) {
// sum the values and format them
$target->textContent = number_format(
$target->textContent + $source->textContent, 2
);
} elseif ($source) {
// if the child does not exists in the first node move it over
$firstItem->appendChild($source);
}
}
$item->parentNode->removeChild($item);
}
}
}
echo $document->saveXML();
PHP: Updating XML from PHP and Saving
You COPY the scalar value (string) into a variable. Then you change the variable.
$qtyNode = $qtyNode->item(0)->nodeValue;
if ($itemNumberNode == $itemNumber)
{
$qtyNode++;
echo $qtyNode;
}
$qtyNode
is not a DOMNode
object, but a string variable.You will have to change the DOMNode::$nodeValue property directly or assign the variable to it.
$qtyNode = $qtyNode->item(0);
if ($itemNumberNode == $itemNumber)
{
$qtyNode->nodeValue++;
echo $qtyNode->nodeValue;
}
PHP Change XML node values
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 How to modify xml file using PHP
You can use the DOMDocument from PHP.
You load your file and than loop trough the childNodes of the document.
<?php
$dom=new DOMDocument();
$dom->load("file.xml");
$root=$dom->documentElement; // This can differ (I am not sure, it can be only documentElement or documentElement->firstChild or only firstChild)
$nodesToDelete=array();
$markers=$root->getElementsByTagName('marker');
// Loop trough childNodes
foreach ($markers as $marker) {
$type=$marker->getElementsByTagName('type')->item(0)->textContent;
$title=$marker->getElementsByTagName('title')->item(0)->textContent;
$address=$marker->getElementsByTagName('address')->item(0)->textContent;
$latitude=$marker->getElementsByTagName('latitude')->item(0)->textContent;
$longitude=$marker->getElementsByTagName('longitude')->item(0)->textContent;
// Your filters here
// To remove the marker you just add it to a list of nodes to delete
$nodesToDelete[]=$marker;
}
// You delete the nodes
foreach ($nodesToDelete as $node) $node->parentNode->removeChild($node);
echo $dom->saveXML();
?>
You can save your output XML like this$dom->saveXML(); // This will return the XML as a string
$dom->save('file.xml'); // This saves the XML to a file
To do this parsing in JavaScript you should use jQuery (a small, but powerful library).You can include the library directly from Google Code Repository.
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
The library is cross-browser and very small. It should be cached in many cases, because some sites use it from Google Code$(yourXMLStringOrDocument).find("marker").each(function () {
var marker=$(this);
var type=marker.find('type').text();
var title=marker.find('title').text();
var address=marker.find('address').text();
var latitude=marker.find('latitude').text();
var longitude=marker.find('longitude').text();
});
Related Topics
Object Copy Versus Clone in PHP
Paypal Ipn Bad Request 400 Error
How to Use PHPize After Update to MACos Mojave
Using Moodle Create Users and Enroll Them in Courses via SQL
Exploding by Array of Delimiters
PHP Error: Cannot Use Object of Type Stdclass as Array (Array and Object Issues)
Optimizing MySQL Fulltext Search
Display Custom Data on Woocommerce Admin Order Preview
How to Run PHP File Using Cron Jobs
Function to Add Dashes to Us Phone Number in PHP
Best Way to Identify a User Uniquely
PHP Displaying Unread Mail Count
Can a PHP File Name (Or a Dir in Its Full Path) Have Utf-8 Characters
In a PHP5 Class, When Does a Private Constructor Get Called
Calling a Stored Procedure from Codeigniter's Active Record Class