简体   繁体   中英

Delete elements of an XML file using PHP

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>

Online Demo

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM