前回の投稿で名前空間の扱いがよく分からず、力技で処理してました。 その後ちょっと勉強してデフォルト名前空間を設定するコードを発見。 次のようにすればいいようです。
var ns = xmlobj.namespace(); default xml namespace = ns;
これでxmlの各要素にアクセスできるようになりました。 例えば次のようなxmlファイル「test.xml」を用意して、
<?xml version="1.0" encoding="UTF-8"?> <root xmlns="http://www.dummy.jp"> <msg attr="属性">テキスト</msg> </root>
msg要素にアクセスするには次のようにします。
var xml_text = readFile('test.xml', 'utf-8');
xml_text = xml_text.replace(/^<\?xml.*\?>\s*/, "");
var x = new XML(xml_text);
var ns = x.namespace();
default xml namespace = ns;
print(x.msg);
結果は次のようになりました。
D:\~\rhino1_7R2>java -jar js.jar -w -strict -encoding utf-8 test2.js テキスト
デフォルト名前空間を使わずに、別個に名前空間を書く場合は次のようになります。
var xml_text = readFile('test.xml', 'utf-8');
xml_text = xml_text.replace(/^<\?xml.*\?>\s*/, "");
var x = new XML(xml_text);
var ns = x.namespace();
print(x.ns::msg);
結果は同じです。
これでXMLの編集ができるようになった...と思ったらちょっと変なところもありました。 ノードへのアクセスの仕方を確かめようと次のようなコードを組んだら...
var xml_text = readFile('test.xml', 'utf-8');
xml_text = xml_text.replace(/^<\?xml.*\?>\s*/, "");
var x = new XML(xml_text);
var ns = x.namespace();
default xml namespace = ns;
print('名前空間 : ' + ns + '\n');
print('<' + x.name() + '>');
attrs = x.attributes();
for(i in attrs)
{
var attr = attrs[i];
print(' @' + attr.localName() + ' / @' + attr.name() );
}
print('');
// ルート要素の子孫の全要素名と属性の表示
var elems = x..*;
for(var i in elems)
{
var elem = elems[i];
if(elem.nodeKind() == 'element')
{
print('<' + elem.name() + '>');
//print('<' + elem.localName() + '>');
}
else if(elem.nodeKind() == 'text')
{
print('#text : "' + elem + '"');
}
var attrs = elem.attributes();
for(var j in attrs)
{
print(' @' + attrs[j].name() );
}
}
結果はこれ。
D:\~\rhino1_7R2>java -jar js.jar -w -strict -encoding utf-8 test2.js
名前空間 : http://www.dummy.jp
<http://www.dummy.jp::root>
@xmlns / @http://www.w3.org/2000/xmlns/::xmlns
<http://www.dummy.jp::msg>
@attr
#text : "テキスト"
一言も書いていないsvgの名前空間が出てきたのです。 なぜ?
なんか嫌な感じの結果ですよね。 これがsvgを読んだときの正しい解析結果だったとしても、
- xmlの読み込み。
- javascriptで編集。
- 編集結果をファイルに出力。
で出力するときには「http://www.w3.org/2000/xmlns/::xmlns」という文字列から元の名前空間を復元しなくてはなりません。 やっぱり前回の投稿のやり方の方が面倒が無くていいかも?