XMLの読込みとXSL変換できたので、IE⇒Edge対応はこれにて一件落着と思ったら、XPathを使用しているところがありました。
当然動かない…
XPathの適用にSelectNodesメソッドを使用していたのですが、XMLの読込みをXMLHttpRequestに変更したためか、SelectNodesメソッドが使えなくなっていました。
ということで、こちらも改修したので方法をまとめます。
テストデータ
いろいろと調べたところdocument.evaluateメソッドが使えました。
とりあえずサンプルコードです。
使用するXMLは次の通りです。
※ファイル名はplayer.xml
<?xml version="1.0" encoding="utf-8" ?>
<team>
<name>オリックス・バッファローズ</name>
<players>
<player>
<position>投手</position>
<name>yamamoto</name>
</player>
<player>
<position>投手</position>
<name>miyagi</name>
</player>
<player>
<position>内野手</position>
<name>okada</name>
</player>
<player>
<position>内野手</position>
<name>adachi</name>
</player>
<player>
<position>内野手</position>
<name>mune</name>
</player>
<player>
<position>内野手</position>
<name>kurebayashi</name>
</player>
<player>
<position>外野手</position>
<name>yoshida</name>
</player>
<player>
<position>外野手</position>
<name>sugimoto</name>
</player>
<player>
<position>外野手</position>
<name>fukuda</name>
</player>
</players>
</team>
サンプルコード
続いてHTMLとJavaScriptです。
上記のXMLと併せてWebサーバー上に保管して表示させてください。
ローカル環境だと動作しないので注意です。
35行目でdocument.evaluateメソッドを使用しています。
今回のコードではXMLから外野手をXPathを適用して抽出しています。
※自作関数は、関数名を「my_」から始めてあります
※Edge、Google Chromeで動作確認済
<!DOCTYPE html>
<html>
<head>
<script>
// onload時に実行
function my_onLoad(){
const objXml = my_loadXML('./player.xml');
let outfielder_list = my_getPlayer(objXml, '外野手');
document.write('<h3>外野手一覧</h3>');
for (let i=0; i<outfielder_list.length; i++){
document.write(outfielder_list[i] + '<br>');
}
}
// XMLを読み込む
// path : 読み込むXMLのパス
function my_loadXML(path){
let objXml = new XMLHttpRequest();
objXml.open('GET', path, false);
objXml.send('');
return objXml.responseXML;
}
// positionで指定した選手を配列で返す
function my_getPlayer(objXml, position) {
// XPathを作成
let xPath = "//player/name[../position='" + position + "']";
// XPathを適用
let result = objXml.evaluate(xPath, objXml, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
// XPathを適用した結果を配列に保存
let result_list = new Array();
let r;
while (r = result.iterateNext()) {
result_list.push(r.textContent);
}
return result_list;
}
</script>
</head>
<body onload='my_onLoad()'>
</body>
</html>
実際に実行すると、下記の様に表示されます。
document.evaluateメソッドの構文と引数
var resultNode = document.evaluate(
xpathExpression,
contextNode,
namespaceResolver,
resultType,
result
);
引数名 | 説明 |
---|---|
xpathExpression ※必須 | XPath |
contextNode ※必須 | XPathを適用するノード |
namespaceResolver | 任意の名前空間接頭辞 ※nullでよさそう |
returnType | XPathを適用した戻り値の種類を指定 |
result | 既存の XPathResult ※nullでよさそう |
returnType(戻り値の種類)で設定できる値
定数 | 値 | 説明 |
---|---|---|
ANY_TYPE | 0 | 戻り値を自動判別 |
NUMBER_TYPE | 1 | 数値、count()などで使用 |
STRING_TYPE | 2 | 文字列 |
BOOLEAN_TYPE | 3 | ブール値 |
UNORDERED_NODE_ITERATOR_TYPE | 4 | ノードセット ドキュメントと順序が異なることがある ドキュメントを変更すると、イテレーションが無効になる |
ORDERED_NODE_ITERATOR_TYPE | 5 | ドキュメント順のノードセット ドキュメントを変更すると、イテレーションが無効になります |
UNORDERED_NODE_SNAPSHOT_TYPE | 6 | ノードのスナップショット ドキュメントと順序が異なることがある |
ORDERED_NODE_SNAPSHOT_TYPE | 7 | ドキュメント順のノードのスナップショット |
ANY_UNORDERED_NODE_TYPE | 8 | XPathに一致する単一のノード ※最初のノードとは限らない |
FIRST_ORDERED_NODE_TYPE | 9 | XPathに一致する最初のノード |
XPathを適用するXMLのことです
反復処理のことです
XPathResult.ORDERED_NODE_ITERATOR_TYPEの様に、頭にXPathResultを付けてください
個人的にですが、よく使いそうなのはノードセットとスナップショットな気がします。
今回はノードセット(ORDERED_NODE_ITERATOR_TYPE)を使用しました。
スナップショット(ORDERED_NODE_SNAPSHOT_TYPE)を使用する方法はこちら
※ノードセットとスナップショットでは結果の取り出し方が違います