MEXSLT
XSLT風のMXMLを書く事でXMLParserを作ることができます
きっと、AS3で書くよりも分かりやすいソースコードにならないかと思ったんです
コード
必須ライブラリ
MEXSLTは以下のライブラリを使用しています
使い方
まずこんなXMLを読み込むとしましょう
<?xml version="1.0" encoding="UTF-8"?> <records> <record> <name>宇多田 信輔</name> <ruby>うただ しんすけ</ruby> <mail>utada_shinsuke@example.com</mail> <sex>男</sex> <age>65</age> <birthday>1944/1/1</birthday> <married>既婚</married> <bloodtype>A型</bloodtype> <prefecture>埼玉県</prefecture> <curry>ぶっかけ・せき止め派</curry> </record> <record> <name>竹下 未來</name> <ruby>たけした みらい</ruby> <mail>takeshita_mirai@example.com</mail> <sex>男</sex> <age>24</age> <birthday>1984/10/12</birthday> <married>既婚</married> <bloodtype>A型</bloodtype> <prefecture>新潟県</prefecture> <curry>ぶっかけ・せき止め派</curry> </record> <record> <name>北村 翔太</name> <ruby>きたむら しょうた</ruby> <mail>kitamura_shouta@example.com</mail> <sex>男</sex> <age>37</age> <birthday>1972/1/8</birthday> <married>既婚</married> <bloodtype>O型</bloodtype> <prefecture>神奈川県</prefecture> <curry>手前ルー・せき止め派</curry> </record> ... </records>
このXMLを解析して、こんなクラスに情報を格納したいとします
package me.rkome.da.sample.model
{
public class DummyData
{
public function DummyData()
{
}
public var name:String;
public var ruby:String;
public var mail:String;
public var sex:String;
public var age:Number;
public var birthday:Date;
public var married:Boolean;
public var bloodType:String;
public var prefecture:String;
public var curry:String;
public function setBirthday(dateString:String):void
{
var array:Array = dateString.split("/");
birthday = new Date(parseInt(array[0]), parseInt(array[1]), parseInt(array[2]));
}
public function setMarried(marriedString:String):void
{
married = (marriedString == "既婚");
}
public function toString():String
{
return "名前: " + this.name + "\n" +
"よみ: " + this.ruby + "\n" +
"メール: " + this.mail + "\n" +
"性別: " + this.sex + "\n" +
"歳: " + (this.sex == "女" ? this.age - 2 : this.age) + "\n" +
"生年月日: " + this.birthday.toDateString() + "\n" +
"結婚: " + (this.sex == "女" && !this.married && 30 <= this.age ? "募集中" : this.married) + "\n" +
"血液型: " + this.bloodType + "\n" +
"出身: " + this.prefecture + "\n" +
"カレーの食べ方: " + this.curry;
}
}
}
生年月日はDate型、結婚しているかどうかはBoolean型となっています
このクラスの配列を読み込み結果として返してくれるXMLParserをMEXSLTを用いて書くと、こんな風に書けます
<mex:MEXSLT id="parser" output="array">
<mex:xslt>
<mex:Template match="records/record">
<mex:New method="push" product="{DummyData}">
<mex:ValueOf select="name" target="name" />
<mex:ValueOf select="ruby" target="ruby" />
<mex:ValueOf select="mail" target="mail" />
<mex:ValueOf select="sex" target="sex" />
<mex:ValueOf select="age" target="age" />
<mex:ValueOf select="birthday" target="setBirthday" method="invoke" />
<mex:ValueOf select="married" target="setMarried" method="invoke" />
<mex:ValueOf select="bloodtype" target="bloodType" />
<mex:ValueOf select="prefecture" target="prefecture" />
<mex:ValueOf select="curry" target="curry" />
</mex:New>
</mex:Template>
</mex:xslt>
</mex:MEXSLT>
MEXSLTタグ
MEXSLTタグのoutput属性に結果を返すデータ形式をarray、objectのどちらかを指定します
そして、MEXSLTタグのxsltプロパティにXMLを解析するルールを記述します
Templateタグ
Templateタグを使ってターゲットとするXMLタグの指定をmatch属性にXPathを使って記述します
サンプルの場合だと『records/record』と書いているので、<records>の子の<record>を対象とするよう指定しています
Newタグ
次に、指定したXMLタグをどんなクラスオブジェクトに変換するかをNewタグを使って指定します
method属性には、assign・push・invokeのいずれかを指定します
- pushの場合、生成されたオブジェクトは出力配列にpushされます
- assignの場合、生成されたオブジェクトは出力オブジェクトのtarget属性で指定したプロパティに設定されます
- invokeの場合、target属性で指定した文字列を関数名として認識して、生成されたオブジェクトを引数に渡して関数を呼び出します
サンプルでは、MEXSLTタグにoutput属性を設定しているので、methodにはpushを指定しています
これで生成されたDummyData?クラスのインスタンスは出力配列に追加されます
product属性には生成するクラスを指定します
ValueOf?タグ
そして、<record>の中身をValueOf?タグを使ってNewタグが生成するオブジェクトに代入します
- select属性にXPathで代入する子要素、属性名を指定します
- target属性に代入先のプロパティ名、または関数名を指定します
- method属性に設定方法(assign、push、invoke)を設定します
- required属性にtrueを設定すると、select属性で指定した要素が読み込んだXMLにない場合に解析エラーを投げるようになります
- defaultValue属性に値を設定する事で、select属性で指定した要素が読み込んだXMLにない場合にデフォルトの値を設定するようになります
こうして出来たXMLParserは、こんな感じに使うことで、XML読み込みを行います
var xml:String = "<records>さっきのXML...</records>";
var result:Array = parser.parse(new XML(xml));
for each (var data:DummyData in result)
{
println(data.toString());
println("================================");
}
required属性を指定している場合は、XML解析エラーを投げることがあるので、try-catchで例外処理を書いてください
ここで説明したサンプルはas3/MEXSLT/MEXSLTSampleにいれてあります
実際の動作は、しばらくはそちらで確認してください
ライセンス
- MIT License
- xpath-as3はNew BSD Licenseです
つくったひと
darkomeme (d [あっと] rkome.me) blog
TODO
- サンプルを掲載する

