JavaScript で XPath を使って XML を Parse する
2018-11-20XML をクライアントサイドで操作したい場面があったので、 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 から、 pref
と city
の値をもとに、都市の名前を取る ということをやりたいです。
実装
上の 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));
// => 室蘭
詳細
document
の evaluate()
を使います。
evaluate
は var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
のような形で使います。
引数は次の通り。
xpathExpression
: XPath の文字列を指定します。contextNode
: 対象となる document を指定します。namespaceResolver
: 対象の document が名前空間を持っている場合に指定します。持っていなければnull
を指定します。resultType
: 返却されるべき XPathResult のタイプを指定します。上の例では文字列が返されるべきなのでSTRING_TYPE
を指定していますが、一般的にはANY_TYPE
を指定します。実際にどのタイプが返却されたかは、 XPathResult オブジェクトのresultType
の値で確認できます。ノードが返却される場合は、UNORDERED_NODE_ITERATOR_TYPE
になります。result
: 既存の XPathResult を指定した場合は、そのオブジェクトを再利用します。null
を指定した場合は、新たに XPathResult オブジェクトが作成されます。
XPath の指定方法として、今回は 2 つの属性の条件を指定しています。
単独の属性指定であれば city[@pref='${prefId}']
ですが、複数になる場合は and
でつなぎます。
ひとこと
無事に JavaScript で XPath を使って XML をパースすることができました。
今回は XPathResult が STRING_TYPE
の例でしたが、他のタイプ、特に UNORDERED_NODE_ITERATOR_TYPE
での挙動についてはまだよくわかっていないので、別途 色々試してみようと思います。
comments powered by Disqus