Change Xml Node Element Value in PHP and Save File

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



Leave a reply



Submit