'Filter XML by day and month

Good day, i'm trying to figure out how can i filter xml file to show items of current Month and Day. It's something like "This day in history" where today 14/10 will show xml content with date 14/10 no matter the year. The code is part of a joomla module that i'm trying to customize so i can display my custom historic events.
Kind regards

My xml:

        <?xml version="1.0" encoding="utf-8"?>
    <articles>
        <article>
            <url>/someurl</url>
            <title>Title</title>
            <text><![CDATA[Event info text]]></text>
            <date>1914-10-14</date>
            <date_publish>0</date_publish>
            <image>/image.jpg</image>
        </article>
        <article>
            <url>/someurl</url>
            <title>Title</title>
            <text><![CDATA[Event info text]]></text>
            <date>1945-10-14</date>
            <date_publish>0</date_publish>
            <image>/image.jpg</image>
        </article>
    </articles>

the php file

class NSP_GK5_xml_file_Model {
    // Method to get sources of articles
    static function getSources($config) {
        $content = array();
        // if there are selected files - set the variables
        if($config['xml_file'] != -1 && file_get_contents(__FILE__) && ini_get('allow_url_fopen')) {
            // loading file content
            $file_content = file_get_contents(JPATH_ROOT . DS . 'modules' . DS . 'mod_news_pro_gk5' . DS . 'external_data' . DS . $config['xml_file']);
            //
            $xml = new SimpleXMLElement($file_content);
            //
            if(count($xml->article) > 0) {
                //
                $art = array();
                //
                foreach ($xml->article as $element) {
                    //
                    foreach($element as $key => $value) {
                        $art[$key] = (string) $value;
                    }
                    //
                    array_push($content, (array) $art);
                }
            }
        }
        //
        return $content;
    }
    // Method to get articles in standard mode 
    static function getArticles($items, $config, $amount) { 
        $content = array();
        //
        for($i = $config['offset']; $i < $amount + $config['offset']; $i++) {
            if(isset($items[$i])) {
                array_push($content, $items[$i]);
            }
        }
        // the content array
        return $content; 
    }
}

// EOF


Solution 1:[1]

Use Xpath expressions. The date should a format with fixed length. So you can get away with string comparison.

$month = '10';
$day = '14';
$expression = "//article[substring(date, 6, 5) = '$month-$day']";

$root = new SimpleXMLElement($xmlString);
$articles = [];
foreach ($root->xpath($expression) as $article) {
    $articles[] = [
        'title' => (string)($article->title ?? ''),
        'date' => (string)($article->date ?? ''),
        // ...
    ];
}
var_dump($articles);

You might notice that I read the data explicitly. A generic (abstract) read means that you might miss keys in the result or carry data around that you do not use. It makes your source less stable. So be specific by default.

The same could be implemented in DOM:

$month = '10';
$day = '14';
$expression = "//article[substring(date, 6, 5) = '$month-$day']";

$document = new DOMDocument();
$document->loadXML($xmlString);
$xpath = new DOMXpath($document);

$articles = [];
foreach ($xpath->evaluate($expression) as $article) {
    $articles[] = [
        'title' => $xpath->evaluate('string(title)', $article),
        'date' => $xpath->evaluate('string(date)', $article),
        // ...
    ];
}

var_dump($articles);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ThW