I need to change texts in a XML file using PHP code. Then I created a code to:
1- get the file
2- replace the texts
3- save the file with other name.
Problem is that I am having some issues to replace some text in a xml file.
I am able to replace simples strings but I can not replace text with characters like '<'. Below the real code and files.
Original XML path: http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml
1) This code just changes the text Inmuebles
to xxxxxxxx
. This works fine
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'Inmuebles' => 'xxxxxxxx'
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
2) Now, if I use this code to change the text <Table Name="Inmuebles">
to <xxxxxxxx>
I get a ERROR 500.
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'<Table Name="Inmuebles">' => '<xxxxxxxx>'
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
3) In the same way, if I use this code to remove the text Publicacion
I get a ERROR 500.
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos-NOK.xml';
$xml = file_get_contents($xml_external_path);
$response = strtr($xml, array(
'<Publicacion>' => ''
));
$newXml = $response;
$newXml = simplexml_load_string( $newXml );
$newXml->asXml('/home/csainmobiliaria/www/pisos-NEW.xml');
This is the final result I need to get:http://www.csainmobiliaria.com/imagenes/fotos/pisos-OK.xml
Capture:
DOMDocument allows you to copy structures of nodes, so rather than having to copy all the details individually (which can be prone to missing data when the specification changes), you can copy an entire node (such as <Inmueble>
) from one document to another using importNode()
which has a parameter to indicate that the full content of the element should be copied. This approach also allows you to copy any of the tables using the same function without code changes...
function extractData ( $sourceFile, $table ) {
// Load source data
$source = new DOMDocument();
$source->load($sourceFile);
$xp = new DOMXPath($source);
// Create new data document
$newFile = new DOMDocument();
$newFile->formatOutput = true;
// Create base element with the table name in new document
$newRoot = $newFile->createElement($table);
$newFile->appendChild($newRoot);
// Find the records to copy
$records = $xp->query('//Table[@Name="'.$table.'"]/*');
foreach ( $records as $record ) {
// Import the node to copy and append it to new document
$newRoot->appendChild();
}
// Return the source of the XML
return $newFile->saveXML();
}
echo extractData ($xml_external_path, "Inmuebles");
You could alter the method to return the document as DOMDocument or even a SimpleXML version if you wished to process it further.
For SimpleXML, change the return to...
return simplexml_import_dom($newRoot);
and then you can call it as...
$ret = extractData ($xml_external_path, "Inmuebles");
echo $ret->asXML();
Or if you just want a fixed way of doing this, you can remove the XPath and just use getElementsByTagName()
to find the nodes to copy...
$source = new DOMDocument();
$source->load($xml_external_path);
$newFile = new DOMDocument();
$newRoot = $newFile->createElement("Inmuebles");
$newFile->appendChild($newRoot);
// Find the records to copy
foreach ( $source->getElementsByTagName("Inmueble") as $record ) {
$newRoot->appendChild($newFile->importNode($record, true));
}
echo $newFile->saveXML();
To add the save file name, I've added a new parameter to the function, this new function doesn't return anything at all - it just loads the file and saves the result to the new file name...
function extractData ( $sourceFile, $table, $newFileName ) {
// Load source data
$source = new DOMDocument();
$source->load($sourceFile);
$xp = new DOMXPath($source);
// Create new file document
$newFile = new DOMDocument();
$newFile->formatOutput = true;
// Create base element with the table name in new document
$newRoot = $newFile->createElement($table);
$newFile->appendChild($newRoot);
// Find the records to copy
$records = $xp->query('//Table[@Name="'.$table.'"]/*');
foreach ( $records as $record ) {
// Import the node to copy and append it to new document
$importNode = $newFile->importNode($record, true);
// Add new content
$importNode->appendChild($newFile->createElement("Title", "value"));
$newRoot->appendChild();
}
// Update Foto elements
$xp = new DOMXPath($newFile);
$fotos = $xp->query("//*[starts-with(local-name(), 'Foto')]");
foreach ( $fotos as $foto ) {
$path = $foto->nodeValue;
if( substr($path, 0, 5) == "/www/" ) {
$path = substr($path,4);
}
// Replace node with new version
$foto->parentNode->replaceChild($newFile->createElement("Foto1", $path),
$foto);
}
$newFile->save($newFileName);
}
$xml_external_path = 'http://www.csainmobiliaria.com/imagenes/fotos/pisos.xml';
$xml_external_savepath = 'saveFile.xml';
extractData ($xml_external_path, "Inmuebles", $xml_external_savepath);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With