Node 上で XML ファイルを読み込む方法
各種システム間のデータの受け渡しをする場合には、ファイルにデータを出力して受け渡しすることは多いですよね。
特に XML でのデータのやり取りでは、データの型情報や属性など、きめ細かいデータを受け渡ししやすいのでとても便利です。
ここでは Node.js 上のスクリプトで XML ファイルを読み込む方法について説明します。
Node.js で XML ファイル読み取りのためのライブラリは?
Node.js で XPath を利用して XML ファイルを読み込むためには xpath パッケージを使うのが便利です。MIT ライセンスで使用できます。
xpath は xmldom パッケージと組み合わせて使います。
% npm install xpath % npm install xmldom
ここでは具体的に次の XML のデータを読み取る方法を考えてみましょう。次のファイルを test.xml とします。
<?xml version="1.0" encoding="utf-8"?>
<School xmlns="http://example.com/XMLSchema" version="1.0">
<Name>South High School</Name>
<Address>
<Street>Main St.</Street>
<City>Los Angeles</City>
<State>California</State>
<Country>
<Name>United States</Name>
<Code>US</Code>
</Country>
</Address>
<Students>
<Student sid="1000">
<Name>Mike Smith</Name>
</Student>
<Student sid="1001">
<Name>Hanako Yamda</Name>
</Student>
</Students>
</School>
学校の情報で住所の情報が Address という要素に記載されており、 生徒のリストが Students という要素の下に記載されています。
Node.js 上の JavaScript で実際に XML を読み込んでみよう
単一の XML ノードの読み込み
次の例では上の XML から住所 (Address) 要素内の市 (City) の値を読み込んで出力しています。
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
const fs = require('fs');
const xml = fs.readFileSync('test.xml', "utf-8");
const doc = new dom().parseFromString(xml);
const select = xpath.useNamespaces({
"a": "http://example.com/XMLSchema"
});
const city = select(
"/a:School/a:Address/a:City/text()",
doc, true);
if(city) {
console.log(city.nodeValue);
}
実行結果は次の通り。
Los Angeles
XML ファイル自体は fs.readFileSync() 関数で丸ごと読み込んでいます。 それを xmldom のパーサーで DOM として認識します。
ここでは名前空間が指定されているので、xpath.useNamespaces() で XPath クエリ用の select オブジェクトを作成しています。
select 関数には XPath、XML ドキュメントオブジェクト、及び、単一ノード選択かどうかを示す bool 値を渡します。
XML ノードのリストの読み込み
次はノードのコレクションを取得して、それぞれのノードから文字列の値と属性値を取得してみましょう。
データを取得する部分は Students ノード以下です。
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
const fs = require('fs');
const xml = fs.readFileSync('test.xml', "utf-8");
const doc = new dom().parseFromString(xml);
const select = xpath.useNamespaces({
"a": "http://example.com/XMLSchema"
});
const students = select("/a:School/a:Students/a:Student", doc);
for(const student of students) {
const id = select("string(@sid)", student);
const name = select("a:Name/text()", student);
console.log(`${id}: ${name}`);
}
実行結果は次の通り。
1000: Mike Smith 1001: Hanako Yamda
属性 (attribute) の値は string(@sid) として取得しています。
属性でノードを指定して読み込む
上の例では Student ノードのコレクションを取得して、それをループで全て出力しました。 次は特定の属性を持つノードを XPath のクエリーで直接ひとつだけ取得してみましょう。
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
const fs = require('fs');
const xml = fs.readFileSync('test.xml', "utf-8");
const doc = new dom().parseFromString(xml);
const select = xpath.useNamespaces({
"a": "http://example.com/XMLSchema"
});
const s = select(
"/a:School/a:Students/a:Student[@sid='1001']/a:Name/text()",
doc, true);
console.log(s.nodeValue);
この実行結果は次の通りです。
Hanako Yamda
確かに属性値 @sid="1001" が設定されているノードの名前 (Name) が取得できています。
以上、XML の読み込み方法について説明しました。