##解決する問題
RSSで取得した記事を、日付順にして日付の表示形式を変更する。
今回はRSSでコロナウイルスに関しての記事を取得しました。
##対象読者
・node.jsでxmlを取得する事ができる方。
・express-generatorを触った事がある方。
・xmlの表示形式の知識がある方。
express-generatorを使ってXMLを取得しているところから進めていきます。
##環境
OS: macOS
Node.js: v13.5.0
npm: 6.14.3
express: ~4.16.1
ejs: ~2.6.1,
##RSSで記事を取得した時の状況
記事を取得し表示させると日付順にならず、見づらい
hello.js↓
router.get('/',(req, res, next) => {
var opt = {
host: 'news.google.com',
port: 443,
path: '/rss/search?q=corona&q=korona&hl=ja&gl=JP&ceid=JP:ja'
};
http.get(opt, (res2) => {
var body = '';
res2.on('data',(data) => {
body += data;
});
res2.on('end', () => {
parseString(body.trim(), (err, result) => {
var data = {
title: 'コロナウイルスの最新情報を表示します',
content: result.rss.channel[0].item
};
res.render('hello', data);
})
});
});
});
hello.ejs↓
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title><%= title %></title>
<link rel='stylesheet' href="/stylesheets/style.css" />
</head>
<body>
<header>
<h1><%= title %></h1>
</header>
<div role="main">
<% if (content != null) { %>
<ol>
<% for (var i in content) { %>
<% var obj = content[i]; %>
<li><%= obj.pubDate %><a href="<%=obj.link %>"><%= obj.title %></a></li>
</tr>
<% } %>
</ol>
<% } %>
</div>
</body>
</html>
(今回取得したxml
https://news.google.com/rss/search?q=corona&q=korona&hl=ja&gl=JP&ceid=JP:ja)
##解決策
###①xmlの記事の中のitemを配列に入れていく。
for in を使ってxmlのitemを配列に入れる処理をループさせます。
配列を作る、ループを作る、配列へpushという順番です。
※ソートする為に配列へ入れます。
<!-- 配列を作成 -->
<% var hash = new Array %>
<!-- xmlのitemをループ処理する -->
<% for (var i in content) { %>
<% var obj = content[i]; %>
<!-- itemを配列へ追加 -->
<% hash.push(obj); %>
<% } %>
※ejsの中にjsを書いています。
※content = result.rss.channel[0].item
###②配列をソートして日付順に並べる
<!-- 配列をソートして日付順に変更 -->
<% hash.sort(function(a,b) {
return (a.pubDate < b.pubDate ? 1 : -1);
}); %>
これで配列の中のitemが、xmlのpubDateの日付順に並びました。
※こちらもejsの中にjsを書いています。
※参考にした記事は下に載っています。
###③日付の表示形式を変更
1、配列をfor inでループさせる
2、ループの中にDateオブジェクトを作成
3、日付の形式を変更
4、(西暦2020年を削除)任意
5、ループ処理の中で記事を表示する
<!-- 配列をループ処理 -->
<% for (var i in hash) { %>
<% var obj2 = hash[i] %>
<!-- 日付の表示形式を変更 -->
<%
var date2 = new Date(obj2.pubDate);
var b = date2.toLocaleString('ja-JP', {era:'long'});
obj2.pubDate = b;
%>
<!-- 西暦を削除 -->
<% var obj3_pubDate = obj2.pubDate.replace('西暦2020年', ''); %>
<!-- 表示 -->
<div class="center">
<ul>
<li>
<a href="<%=obj2.link %>">
<div class="Date"><%=obj3_pubDate %></div>
<div class="title"><%=" " + obj2.title %></div>
</a>
</li>
</ul>
</div>
<% } %>
#変更後のコード
hello.ejs↓
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title><%= title %></title>
<link rel='stylesheet' href="/stylesheets/style.css" />
</head>
<div class="style">
<!-- 更新日時を日本語へ変更する -->
<% var update2 = new Date(update);
var update3 = update2.toLocaleString('ja-JP', {era:'long'});
update = update3;
%>
<!-- 更新日時の西暦を消す -->
<% var update4 = update.replace('西暦2020年', ''); %>
</div>
<body>
<header>
<h1><%= title %>更新(<%= update4 %>)</h1>
</header>
<div role="main">
<% if (content != null) { %>
<!-- 配列を作成 -->
<% var hash = new Array %>
<!-- xmlのitemをループ処理する -->
<% for (var i in content) { %>
<% var obj = content[i]; %>
<!-- itemを配列へ追加 -->
<% hash.push(obj); %>
<% } %>
<!-- 配列をソートして日付順に変更 -->
<% hash.sort(function(a,b) {
return (a.pubDate < b.pubDate ? 1 : -1);
}); %>
<!-- 配列をループ処理 -->
<% for (var i in hash) { %>
<% var obj2 = hash[i] %>
<!-- 日付の表示形式を変更 -->
<%
var date2 = new Date(obj2.pubDate);
var b = date2.toLocaleString('ja-JP', {era:'long'});
obj2.pubDate = b;
%>
<!-- 西暦を削除 -->
<% var obj3_pubDate = obj2.pubDate.replace('西暦2020年', ''); %>
<!-- 表示 -->
<div class="center">
<ul>
<li>
<a href="<%=obj2.link %>">
<div class="Date"><%=obj3_pubDate %></div>
<div class="title"><%=" " + obj2.title %></div>
</a>
</li>
</ul>
</div>
<% } %>
<% } %>
</div>
</body>
</html>
hello.js↓
var express = require('express');
var router = express.Router();
var http = require('https');
var parseString = require('xml2js').parseString;
router.get('/',(req, res, next) => {
var opt = {
host: 'news.google.com',
port: 443,
path: '/rss/search?q=corona&q=Coronavirus&hl=ja&gl=JP&ceid=JP:ja'
};
http.get(opt, (res2) => {
var body = '';
res2.on('data',(data) => {
body += data;
});
res2.on('end', () => {
parseString(body.trim(), (err, result) => {
var data = {
title: 'コロナウイルスの最新情報を表示します',
content: result.rss.channel[0].item,
update: result.rss.channel[0].lastBuildDate
};
res.render('hello', data);
})
});
});
});
module.exports = router;
##参考
配列を日付順にソートする方法
https://infoteck-life.com/a0107-js-array-sort-date/
https://www.p-nt.com/technicblog/archives/58
Dateオブジェクトの使い方入門
https://www.sejuku.net/blog/30171
Dateオブジェクトのプロパティ(日付の表示形式を参考にしました。)
https://so-zou.jp/web-app/tech/programming/javascript/grammar/object/date.htm
ループ処理(今回はfor inでループしています。)
https://qiita.com/endam/items/808a084859e3a101ab8f
文字列から指定した文字を削除する(日付の西暦2020年を削除する為に参考にしました。)
https://zukucode.com/2017/04/javascript-string-remove.html