ActionScript2.0でXMLを解析するのってノードを一個一個たどらなくちゃいけなく、とってもてかったるいです。そんなこんなで、ActionScriptでXpathを使えるようにするライブラリを作っちゃった人がいるんですね。
XPath4AS2
http://www.xfactorstudio.com/Actionscript/AS2/XPath/
これだけでも十分便利なんだけど、XMLを書き換えたりするときのためにラッパーを作ってみた。
ソースはこんな感じ。
/*
====================================================
XPathWrapper v1.0 2005
author:sakana sato
e-mail:sakana.sato@nifty.com
an extention of XPath4AS2
http://www.xfactorstudio.com/Actionscript/AS2/XPath/
====================================================
*/
import com.xfactorstudio.xml.xpath.*;
class XPathWrapper {
var myXML:XML;
function XPathWrapper(){
//no constructor
}
function getData( x:XML , _xpath:String){
var t:Array = XPath.selectNodes( x, _xpath );
return t;
}
function setData( x:XML , _xpath:String , _val:String ):XML {
myXML = new XML();
myXML = x;
var targetNode = String( XPath.selectNodes( myXML, _xpath ) );
var targetTextNode = String( XPath.selectNodes( myXML, _xpath+"text()" ) );
var convNode = convSentence(targetNode , targetTextNode , _val );
var convXML = new XML(convSentence(myXML.toString() , targetNode , convNode));
return convXML;
}
function removeData( x:XML , _xpath:String):XML{
myXML = new XML();
myXML = x;
var targetNode = String( XPath.selectNodes( myXML, _xpath ) );
var convXML = new XML(convSentence(myXML.toString() , targetNode , ""));
return convXML;
}
function addData( x:XML , _xpath:String , addingNode:XML):XML{
myXML = new XML();
myXML = x;
var targetNode:Array = XPath.selectNodes( myXML, _xpath );
var convXML = new XML( convSentence(myXML.toString() , targetNode[targetNode.length-1] , targetNode[targetNode.length-1]+addingNode.toString() ));
return convXML;
}
private function convSentence( _str:String , oldKey:String , convkey:String ):String{
var sentenceArray = [];
sentenceArray = _str.split(oldKey);
return sentenceArray.join(convkey);
}
}
_xml = new XML("<root><container><item>アイテム1</item><item attr='aa'>アイテム2</item></container></root>");
var xpw:XPathWrapper = new XPathWrapper();
// こんな感じでnewして
trace( xpw.getData( _xml , "root/container/item/text()" ) );
// こんな風にXpathを書くと「アイテム1」が(配列で)帰ってくる
trace( xpw.getData( _xml , "root/container/item[2]/@attr" ) );
// アトリビュートもお手の物。
trace( _xml=xpw.setData( _xml , "root/container/item[2]/" , "アイテム4") );
// XMLを書き換えるのはこんな感じ。
trace( _xml=xpw.setData( _xml , "root/container/item[2]/@attr" , "アイテム3") );
// アトリビュートの値も書き換えられる。
trace( xpw.removeData( _xml , "root/container/item[1]/" ) );
// ノードごと消したくなったらこんな感じで。
じつはこれ業務で書いたものなのですが、ソースをまんま持ち出すのはどうかと思って家でフルスクラッチで書き直したものなんです。データをセットするところとか、かなりインチキ臭いですけど、まあ動くからいっか。しかも仕事で書いたものよりソースが短くなってるし。
たとえば、FlashでRSSリーダーを作るとして、OPMLをsharedObjectかなんかで保存したり、取り出したりする機能を付けたくなったりしたらこれがあると大幅に簡略化できるんじゃないかな。
たいしたものじゃないですが自由に使ってください。引っ越し祝いということで。