michimani.net

JavaScript で XPath を使って XML を Parse する

2018-11-20

XML をクライアントサイドで操作したい場面があったので、 JavaScript で XML を扱う方法について調べてみました。

基本的には上のリファレンスの通りです。

やりたいこと

今回の対象とするのは次のような XML です。

<?xml version="1.0" encoding="utf-8"?>
<cities version="1.0.0">
    <city pref="1" city="1">札幌</city>
    <city pref="1" city="2">函館</city>
    <city pref="1" city="3">小樽</city>
    <city pref="1" city="4">室蘭</city>
    <city pref="2" city="1">弘前</city>
    <city pref="2" city="2">青森</city>
    <city pref="2" city="3">八戸</city>
    <city pref="3" city="1">盛岡</city>
    <city pref="3" city="2">釜石</city>
    <city pref="3" city="3">宮古</city>
</cities>

この XML から、 prefcity の値をもとに、都市の名前を取る ということをやりたいです。

実装

上の XML が cities.xml として、やりたいことを JavaScript で実現するためのコードです。

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', () => {
    var citiesXml = xhr.responseXML;
});
xhr.addEventListener('error', () => {
    console.error('Failed to load xml.');
});
xhr.open('GET', '/path/to/cities.xml');
xhr.send();

function getCityName(prefId, cityId) {
    return citiesXml.evaluate(`//city[@pref='${prefId}' and @city='${cityId}']`, citiesXml, null, XPathResult.STRING_TYPE, null).stringValue;
}

console.log(getCityName(1,4));

// => 室蘭

詳細

documentevaluate() を使います。
evaluatevar xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result ); のような形で使います。

引数は次の通り。

XPath の指定方法として、今回は 2 つの属性の条件を指定しています。
単独の属性指定であれば city[@pref='${prefId}'] ですが、複数になる場合は and でつなぎます。

ひとこと

無事に JavaScript で XPath を使って XML をパースすることができました。
今回は XPathResult が STRING_TYPE の例でしたが、他のタイプ、特に UNORDERED_NODE_ITERATOR_TYPE での挙動についてはまだよくわかっていないので、別途 色々試してみようと思います。

以上、よっしー (michimani) でした。