tag:crieit.net,2005:https://crieit.net/tags/rest/feed
「rest」の記事 - Crieit
Crieitでタグ「rest」に投稿された最近の記事
2019-06-23T23:09:43+09:00
https://crieit.net/tags/rest/feed
tag:crieit.net,2005:PublicArticle/15156
2019-06-23T23:09:10+09:00
2019-06-23T23:09:43+09:00
https://crieit.net/posts/NodeJS-XML
NodeJSでXMLをパースする
<p>相変わらず、あちこち手を広げ過ぎてる気がしますが。</p>
<h2 id="背景"><a href="#%E8%83%8C%E6%99%AF">背景</a></h2>
<p>カラオケ「DAM」のサーバから採点履歴のデータを取得する際、<br />
RESTで返ってくるのがXMLなのでパース方法を調査した。</p>
<h2 id="使うライブラリ"><a href="#%E4%BD%BF%E3%81%86%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA">使うライブラリ</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/fast-xml-parser">fast-xml-parser</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/he">he(HTML entities)</a></li>
</ul>
<h1 id="fast-xml-parser"><a href="#fast-xml-parser">fast-xml-parser</a></h1>
<h2 id="パース対象とするデータ形式"><a href="#%E3%83%91%E3%83%BC%E3%82%B9%E5%AF%BE%E8%B1%A1%E3%81%A8%E3%81%99%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%BD%A2%E5%BC%8F">パース対象とするデータ形式</a></h2>
<pre><code class="xml"><document xmlns="https://www.clubdam.com/app/damtomo/membership/MarkingDxListXML" type="2.2">
<result>
<status>OK</status>
<statusCode>0000</statusCode>
<message/>
</result>
<data>
<totalPage>40</totalPage>
<page>1</page>
<cdmCardNo>******</cdmCardNo>
</data>
<list count="5">
<data>
<marking requestNo="3809-63" artist="fripSide" contents="black bullet" play="0" reportCommentNo="2252" chartInterval="86" chartStability="75" chartExpressiveness="85" chartVibrateLongtone="85" chartRhythm="86" highPitch="79" lowPitch="56" highTessitura="67" lowTessitura="56" modulation="8" measure="15" sob="1" fall="2" timing="5" longTone="7" vibrato="5" vibratoType="1" vibratoSumSeconds="7.9" averageTotalPoint="80187" averagePitch="74" averageStability="67" averageExpressiveness="74" averageVibrateLongtone="53" averageRhythm="95" lastPoint="92804" date="2019/06/15 **:**:**">90.979</marking>
</data>
<data>
.....
</data>
</list>
</document>
</code></pre>
<h2 id="パースオプション"><a href="#%E3%83%91%E3%83%BC%E3%82%B9%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3">パースオプション</a></h2>
<h3 id="attributeNamePrefix"><a href="#attributeNamePrefix">attributeNamePrefix</a></h3>
<p>パースした際にattributeのprefixにつける文字を指定する。</p>
<h3 id="ignoreAttributes"><a href="#ignoreAttributes">ignoreAttributes</a></h3>
<p>これをtrueにしているとxmlのattributeを無視してしまう。<br />
今回はmarkingの属性を取りたいので<strong>false</strong></p>
<pre><code class="javascript">var options = {
attributeNamePrefix : "@_",
attrNodeName: "attr", //default is 'false'
textNodeName : "#text",
ignoreAttributes : false,
ignoreNameSpace : false,
allowBooleanAttributes : false,
parseNodeValue : true,
parseAttributeValue : false,
trimValues: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
localeRange: "", //To support non english character in tag/attribute values.
parseTrueNumberOnly: false,
attrValueProcessor: a => he.decode(a, {isAttributeValue: true}),//default is a=>a
tagValueProcessor : a => he.decode(a) //default is a=>a
};
</code></pre>
<h2 id="200件(上限)取ってくるコード"><a href="#200%E4%BB%B6%28%E4%B8%8A%E9%99%90%29%E5%8F%96%E3%81%A3%E3%81%A6%E3%81%8F%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89">200件(上限)取ってくるコード</a></h2>
<p>1ページに5件ずつあるのでカウンタjで40まで取りに行く。<br />
resultArrayに結果を詰めていって、成功したらレスポンスとして返す。</p>
<pre><code class="typescript"> public loadData(req:express.Request,res:express.Response) :void{
(async()=>{
let cdmCardNo = '******'//ユーザ固有のtokenを入れる
let url = 'https://www.clubdam.com/app/damtomo/membership/MarkingDxListXML.do?cdmCardNo='+ cdmCardNo
let resultArray = []
for(let j = 0 ; j < 40 ; j++){
let response = await fetch(url + '&pageNo=' + (j + 1))
let data = await response.text()
//let data = response.json()
let xmlData = parser.parse(data ,options);
console.log(xmlData)
if(xmlData.document.list.data === undefined){
break;
}
for(let i = 0; i < xmlData.document.list.data.length; i++){
resultArray.push(xmlData.document.list.data[i])
}
}
res.json(resultArray)
})().catch(err=>{
console.error(err)
res.sendStatus(500)
})
}
</code></pre>
ckoshien