我正试图使用PHP从XML中删除一个特定的节点。这是XML:的结构
<ArrivingFlights>
<flight>
<to>Michelle</to>
<from>Brianna xx</from>
<imagepath>0001.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>17:00</time>
<date>18/12/15</date>
</flight>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
</ArrivingFlights>
我有一个PHP文件,我用它来获取FileName,这样我就可以删除基于该文件名的节点并替换它
<?php
$id = $_GET['imagepath'];
$xmldoc = new DOMDocument();
$xmldoc->load('newcoke.xml');
$root = $xmldoc->documentElement;
$fnode = $root->firstChild;
// we retrieve the chapter and remove it from the book
$items = $xmldoc->getElementsByTagName('flight');
foreach ($items as $item){
$node = $item->getElementsByTagName('imagepath')->item(0);
if ($node->nodeValue == $id){
$node->parentNode->removeChild($node);
}
}
$xmldoc->save('newXmlFile.xml');
?>
这种排序是有效的,当我查看newFile.xml时,它正在删除"ImagePath",但我希望它删除整个"flight"节点,所以基本上是它的父节点。这是我通过0001.jpg得到的结果:
<flight>
<to>Michelle</to>
<from>Brianna xx</from>
<templateStyle>template1</templateStyle>
<time>17:00</time>
<date>18/12/15</date>
</flight>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
考虑使用XSLT,这是一种用于重构XML文件的专用语言。PHP维护一个XSLT1.0处理器。因此,不需要foreach
循环或if
逻辑条件,因为样式表脚本将非常有效地处理此类处理。您甚至可以将脚本嵌入PHP中,以动态传递$id
变量:
PHP带有嵌入式XSLT
// Retrieve imagepath value
$id = $_GET['imagepath'];
// Load the XML source
$doc = new DOMDocument();
$doc->load('Flights.xml');
// Parse XSLT
$xsl = new DOMDocument;
$xslstr = '<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="flight[imagepath='''.$id.''']"/>
</xsl:transform>';
$xsl->loadXML($xslstr);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXml = $proc->transformToXML($doc);
// Save output to file
$xmlfile ='Output.xml';
file_put_contents($xmlfile, $newXml);
输出
<?xml version="1.0" encoding="UTF-8"?>
<ArrivingFlights>
<flight>
<to>Ger</to>
<from>Mammy xx</from>
<imagepath>0002.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>08:00</time>
<date>21/12/15</date>
</flight>
<flight>
<to>Ciara</to>
<from>Vikki xx</from>
<imagepath>0003.jpg</imagepath>
<templateStyle>template1</templateStyle>
<time>11:00</time>
<date>17/12/15</date>
</flight>
</ArrivingFlights>
由于flight
是$item
,因此应该删除$item
而不是$node
:
$item->parentNode->removeChild($item);
您可以根据需要多次使用parentNode
,尽管这显然需要您确信您的XML结构不会改变。在这种特殊的情况下,你只需要进一步提升一个级别,比如:
$node->parentNode->parentNode->removeChild($node->parentNode);
但是,由于您已经处于设置$item
的循环中,只需直接删除它:
$item->parentNode->removeChild($item);