【JS】RSSで取得した記事を日付順にし、表示形式を変更する(Javascript・node.js)

##解決する問題
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↓

```javascript
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↓

```html
<!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>
```
<img width="1405" alt="スクリーンショット 2020-03-29 15.55.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558434/c80d5685-d08f-9f78-066c-41a8067158ed.png">

(今回取得した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という順番です。

※ソートする為に配列へ入れます。

```javascript
<!-- 配列を作成 -->
<% 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

###②配列をソートして日付順に並べる

```js
<!-- 配列をソートして日付順に変更 -->
<% hash.sort(function(a,b) {
    return (a.pubDate < b.pubDate ? 1 : -1);
}); %>
```
これで配列の中のitemが、xmlのpubDateの日付順に並びました。
※こちらもejsの中にjsを書いています。
※参考にした記事は下に載っています。

###③日付の表示形式を変更
１、配列をfor inでループさせる
２、ループの中にDateオブジェクトを作成
３、日付の形式を変更
４、(西暦2020年を削除)任意
５、ループ処理の中で記事を表示する

```js
<!-- 配列をループ処理 -->
<% 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>
<% } %>
```

##表示結果
css追加前↓
<img width="80%" alt="スクリーンショット 2020-03-29 17.25.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558434/d2df2b81-e085-31fb-4917-2a0e55ceea78.png">

css追加後↓
<img width="80%" alt="スクリーンショット 2020-03-29 17.26.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558434/d71e75a5-f8a3-db5d-64a0-33c3d4ff3a30.png">

#変更後のコード
hello.ejs↓

```html
<!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↓

```javascript

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