たまにあるけど毎度忘れて検索するハメになるのでメモ。
リファレンスはXML DOM Objects/Interfaces。といってもMSのURLはコロコロ変わるからURL載せてもあんまり意味ない。
まずはオブジェクトを作成
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0"); var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.6.0"); var xmlDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0"); var xmlDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0");
まず指定するProgIDだがリファレンスにはこれだけ載ってる。3.0とか6.0はVerだからいいとしてFreeThreadedDOMDocumentつーのはマルチスレッドの必要があるならならこっち使えって事らしい。WSHでそんな事出来ないので関係ない。
XMLをロード
xmlDoc.load(path); xmlDoc.loadXML(xml);
loadメソッドはXMLのPathを指定するのであってXMLドキュメント自体を指定するのではない。web上にあるXMLを読み込むような場合はloadXMLで読み込む。共に戻り値はBoolean。読み込みの成功失敗はこれで判断出来る。
XMLロード時のオプション
xmlDoc.async = false; xmlDoc.validateOnParse = false; xmlDoc.resolveExternals = false;
async | 同期非同期フラグ。非同期ならtrueでこれがdefalt。 |
validateOnParse | XMLをパースする際のvalidなドキュメントであるかの妥当性検証のフラグ。 |
resolveExternals | DTDのフラグ。 |
非同期で扱う事なんかあまりないだろうしXMLの厳密な検証なんてする事も少ないだろう。最近DTD自体が使われなくなっているのでこれもfalseでよし。この3行をおまじないと思ってloadの前に置いておけばいいだろう。
XPathで目的のデータを取得する場合
xmlDoc.setProperty("SelectionLanguage", "XPath");
selectSingleNodeやselectNodesで与える引数は互換性を確保する為にdefaltではXSLPatternとなっている。XSLPatternなんてもう廃止されて久しいんだけど。そんな訳でXPathを使うには上記の様なおまじないを唱える必要がある。
XMLにおける名前空間の問題
<?xml version="1.0" encoding="UTF-8" ?> <RDF xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <item> <title>foo</title> <dc:description>bar</description> </item> </RDF>
こんなXMLがあるとしよう。そこらのRSSをサンプルにして適当にこしらえたんだけど。この中のitem要素を抜き出したいが一体どうすればいい。とりあえずselectNodesで抜き出してみよう。
xmlDoc.selectNodes("//item");
うーん上手く動かない。調べると名前空間を指定しないと駄目らしい。名前空間はsetPropertyを使って設定する。
xmlDoc.setProperty("SelectionNamespaces", "xmlns='http://purl.org/rss/1.0/' xmlns:dc='http://purl.org/dc/elements/1.1/'");
そしてもう一度selectNodesで抜き出してみよう。やっぱり動かない。
結論を言うとitem要素には「xmlns="http://purl.org/rss/1.0/"」というprefixのない名無しの名前空間が設定されている。これを指定する必要があるがprefixがないので指定しようがない。仕方がないのでこうする。
xmlDoc.setProperty("SelectionNamespaces", "xmlns:defalt='http://purl.org/rss/1.0/'"); xmlDoc.selectNodes("//defalt:item");
名無しだった名前空間にdefaltというprefixを付けた。selectNodesでもdefalt:itemと名前空間を指定した。この適当に付けたprefixはaでもbでも識別できれば何でもいい。