Фильтрация XML-файла с помощью PHP

Я хочу загрузить XML-файл, а затем удалить все <Charge> где <DispositionDate> больше / старше, чем 7 лет. Формат даты – ГГГГ-ММ-ДД.

Пример XML:

 <BackgroundReports userId="" password="" account="" > <BackgroundReportPackage> <Screenings> <Screening type="criminal" qualifier=""> <CriminalReport> <CriminalCase> <AgencyReference type="Docket"> <IdValue>CR-0870120-09</IdValue> </AgencyReference> <Charge> <ChargeId> <IdValue>1</IdValue> </ChargeId> <ChargeOrComplaint>DUI: HIGHEST RTE OF ALC (BAC .16+) 1ST OFF</ChargeOrComplaint> <ChargeTypeClassification>unknown</ChargeTypeClassification> <DispositionDate>2009-04-07</DispositionDate> </Charge> <Charge> <ChargeId> <IdValue>2</IdValue> </ChargeId> <ChargeOrComplaint>CARELESS DRIVING</ChargeOrComplaint> <ChargeTypeClassification>unknown</ChargeTypeClassification> <DispositionDate>2010-08-02</DispositionDate> </Charge> <Charge> <ChargeId> <IdValue>3</IdValue> </ChargeId> <ChargeOrComplaint>STATUTE: 475 PC</ChargeOrComplaint> <ChargeTypeClassification>misdemeanor</ChargeTypeClassification> <OffenseDate>1988-11-05</OffenseDate> <Disposition>CONVICTED</Disposition> <DispositionDate>1988-11-09</DispositionDate> <DispositionDate>1988-11-05</DispositionDate> <DispositionDate>1988-11-09</DispositionDate> </Charge> </CriminalCase> </CriminalReport> </Screening> </Screenings> </BackgroundReportPackage> </BackgroundReports> 

Я знаю, как открывать и закрывать / сохранять файл с помощью PHP, я не знаю, как удалить часть, которую я не хочу … Если бы кто-нибудь помог мне с этим, я был бы чрезвычайно благодарен!

Вы можете использовать SimpleXML , DOM или XSL для этого.

Пример XML ( сокращен для краткости (из версии 1 вашего вопроса) ):

 $xml = <<< XML <CriminalCase> <Charge> <DispositionDate>1995-12-21</DispositionDate> </Charge> <Charge> <DispositionDate>2010-12-21</DispositionDate> </Charge> </CriminalCase> XML; 

С помощью SimpleXml

 $sevenYearsAgo = new DateTime('-7 years'); $CriminalCase = new SimpleXmlElement($xml); for ($i = 0; $i < $CriminalCase->Charge->count(); $i++) { $dispositionDate = new DateTime($CriminalCase->Charge->DispositionDate); if ($dispositionDate < $sevenYearsAgo) { unset($CriminalCase->Charge[$i]); } } echo $CriminalCase->asXml(); с $sevenYearsAgo = new DateTime('-7 years'); $CriminalCase = new SimpleXmlElement($xml); for ($i = 0; $i < $CriminalCase->Charge->count(); $i++) { $dispositionDate = new DateTime($CriminalCase->Charge->DispositionDate); if ($dispositionDate < $sevenYearsAgo) { unset($CriminalCase->Charge[$i]); } } echo $CriminalCase->asXml(); 

С DOM

 $dom = new DOMDocument; $dom->loadXml($xml); $xpath = new DOMXPath($dom); $oldCases = $xpath->query( sprintf( '//Charge[substring-before(DispositionDate, "-") < %d]', date('Y', strtotime('-7 years')) ) ); foreach ($oldCases as $oldCase) { $oldCase->parentNode->removeChild($oldCase); } echo $dom->saveXml(); 

С XSLT

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date"> <xsl:output indent="yes" method="xml"/> <xsl:template match="/"> <CriminalCase> <xsl:apply-templates /> </CriminalCase> </xsl:template> <xsl:template match="Charge"> <xsl:if test="date:year(DispositionDate) &gt; date:year() - 7"> <xsl:copy-of select="."/> </xsl:if> </xsl:template> </xsl:stylesheet> 

а затем использовать этот код PHP для его преобразования

 $doc = new DOMDocument(); $xsl = new XSLTProcessor(); $doc->loadXml($xsl); $xsl->importStyleSheet($doc); $doc->loadXml($xml); echo $xsl->transformToXML($doc); 

Вот несколько советов о том, как начать работу:

  1. Вам нужно проанализировать XML с чем-то, с чем немного легче работать. PHP имеет библиотеку под названием SimpleXML .
  2. Прокрутите данные и удалите объекты старше 7 лет. Чтобы сравнить даты, вы должны сначала преобразовать даты, полученные вами из XML, в то, что PHP может обрабатывать как дату. Взгляните на strtotime который дает вам strtotime метку (секунды с 1970 года, на самом деле 1901 для версии> 5.1.0) или DateTime, которая поддерживает даты до 1970 года.
  3. Чтобы проверить, была ли полученная дата старше 7 лет назад, вам нужно (в одну сторону) вычесть временную метку с текущей меткой времени и посмотреть, превышает ли это значение более 7 лет в секундах. Или, если вы используете DateTime, вы можете взглянуть на DateTime :: diff . Удалите объекты, которые вы повторяете, старше 7 лет ( unset ).
  4. Чтобы сохранить как XML снова, взгляните на SimpleXMLElement :: asXML

Надеюсь, это поможет!