I need to delete elements of an XML file using PHP.
This is my XML file
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetVehiculesLocationResponse xmlns="http://google.fr/">
<GetVehiculesLocationResult>
<Location>
<idVH>001</idVH>
<date>2020-06-30T09:06:39</date>
<latitude>111111</latitude>
<longitude>11111</longitude>
</Location>
<Location>
<idVH>002</idVH>
<date>2020-04-02T13:45:51</date>
<latitude>1111111</latitude>
<longitude>111111</longitude>
</Location>
<Location>
<idVH>11111111</idVH>
<date>2020-03-24T21:49:46</date>
<latitude>1111111</latitude>
<longitude>11111111</longitude>
</Location>
</GetVehiculesLocationResult>
</GetVehiculesLocationResponse>
</soap:Body>
</soap:Envelope>
I want to delete elements (in this case Location
) where idVH
is a certain value (in this case 002)
I have tried this but it doesn't work
$xml1 = simplexml_load_string($result);
$items = $xml1->xpath("/soap:Envelope/soap:Body/GetVehiculesLocationResponse/GetVehiculesLocationResult/Location[idVH = 002]");
foreach ($items as $i) unset($i[0]);
echo $xml1->asXML();
The issue is that the element GetVehiculesLocationResponse
defines a new default namespace, so that and the child elements are all in that new namespace...
<GetVehiculesLocationResponse xmlns="http://google.fr/">
So first register the new namespace and then use it as a prefix in the lower level elements...
$xml1->registerXPathNamespace("d", "http://google.fr/");
$items = $xml1->xpath("/soap:Envelope/soap:Body/d:GetVehiculesLocationResponse/d:GetVehiculesLocationResult/d:Location[d:idVH = '002']");
Consider XSLT (sibling to XPath), the special-purpose language designed to transform XML files and especially best suited for processing many elements. In fact, you can even pass parameters like 001
from PHP to XSLT. PHP can run XSLT 1.0 scripts with its xsl class using DOMDocument
library.
XSLT
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:googl="http://google.fr/">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- DEFINE PARAM WITH DEFAULT -->
<xsl:param name="id_param">001</xsl:param>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- KEEP NODES BY PARAM VALUE -->
<xsl:template match="googl:GetVehiculesLocationResult">
<xsl:copy>
<xsl:copy-of select="googl:Location[googl:idVH != $id_param]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP (pass parameters to XSLT in loop)
// LOAD XML
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load($data->xmlFile);
// LOAD XSLT
$xsl = new DOMDocument('1.0', 'UTF-8');
$xsl->load('XSLT_Script.xsl');
// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
foreach($param as array('001', '002')) {
// SET PARAMETER VALUE
$proc->setParameter('', 'id_param', $param);
// TRANSFORM SOURCE
$xml = $proc->transformToDoc($xml);
}
// ECHO TO SCREEN
echo $xml->saveXML();
// SAVE TO FILE
file_put_contents($data->xmlFile, $xml);
Output
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<GetVehiculesLocationResponse xmlns="http://google.fr/">
<GetVehiculesLocationResult>
<Location>
<idVH>11111111</idVH>
<date>2020-03-24T21:49:46</date>
<latitude>1111111</latitude>
<longitude>11111111</longitude>
</Location>
</GetVehiculesLocationResult>
</GetVehiculesLocationResponse>
</soap:Body>
</soap:Envelope>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.