'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 |
