XmlPullParserをイベントドリブン対応にしてみた。
XmlPullParserも基本SAXみたいに上から順番に解析するだけ。でもSAXと違ってコールバックしてくれないので解析処理とEventTypeを確認しながら実装しなくてはならないためコードが冗長的になる。
なのでSAXのコールバック的なインタフェースとアダプターを作った
クラスとか
- XmlPullpaHandler:イベントハンドラ
- XmlPullpaAdapter:イベントハンドラの処理を空実装したアダプタクラス
- XmlPullpaException:例外クラス
- XmlPullpaReader:XmlPullParserを使ってコールバックしてくれるリーダクラス
package com.example.xml.helper; public interface XmlPullpaHandler { /** * 文書の解析開始 * @throws XmlPullpaException */ void startDocument() throws XmlPullpaException; /** * 文書の解析終了 * @throws XmlPullpaException */ void endDocument() throws XmlPullpaException; /** * 要素開始 * @param name * @param depth * @throws XmlPullpaException */ void startTag(String name, int depth) throws XmlPullpaException; /** * 要素の終了 * @param name * @param depth * @throws XmlPullpaException */ void endTag(String name, int depth) throws XmlPullpaException; /** * 属性データ */ void apperAttribute(String parent, String name, String value, int index) throws XmlPullpaException; /** * 文字データ */ void apperText(String parent, String value) throws XmlPullpaException; /** * 無視できる文字列 * @throws XmlPullpaException */ void ignoreWhitespace() throws XmlPullpaException; }
■イベントハンドラの処理を空実装したアダプタクラス
package com.example.xml.helper; public abstract class XmlPullpaAdapter implements XmlPullpaHandler { /** * 文書の解析開始 * * @throws XmlPullpaException */ @Override public void startDocument() throws XmlPullpaException { } /** * 文書の解析終了 * * @throws XmlPullpaException */ @Override public void endDocument() throws XmlPullpaException { } /** * 要素開始 * * @param name * @param depth * @throws XmlPullpaException */ @Override public void startTag(String name, int depth) throws XmlPullpaException { } /** * 要素の終了 * * @param name * @param depth * @throws XmlPullpaException */ @Override public void endTag(String name, int depth) throws XmlPullpaException { } /** * 属性データ */ @Override public void apperAttribute(String parent, String name, String value, int index) throws XmlPullpaException { } /** * 文字データ */ @Override public void apperText(String parent, String value) throws XmlPullpaException { } /** * 無視できる文字列 */ @Override public void ignoreWhitespace() throws XmlPullpaException { } }
■例外クラス
package com.example.xml.helper; public class XmlPullpaException extends Exception { private static final long serialVersionUID = 1L; public XmlPullpaException(String str) { super(str); } }
■XmlPullParserを使ってコールバックしてくれるリーダクラス
getByteArrayFromURLメソッドは前の記事参照
package com.example.xml.helper; import java.io.IOException; import java.io.StringReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.res.XmlResourceParser; import android.util.Xml; public class XmlPullpaReader { private XmlPullpaHandler handler; private XmlPullParser xmlParser; public void setHandler(XmlPullpaHandler handler) { this.handler = handler; } public void setXmlParser(XmlPullParser xmlParser) { this.xmlParser = xmlParser; } public void parse(String xml){ this.xmlParser = Xml.newPullParser(); try { this.xmlParser.setInput(new StringReader(xml)); } catch (XmlPullParserException e) { e.printStackTrace(); } } public void parse(XmlResourceParser parser){ this.xmlParser = parser; } public void read() { try { int eventType = xmlParser.getEventType(); String currentTag = null; while (eventType != XmlPullParser.END_DOCUMENT) { switch(eventType){ case XmlPullParser.START_DOCUMENT: this.handler.startDocument(); break; case XmlPullParser.END_DOCUMENT: //while終了条件で判定するんでここには来なかったりする this.handler.endDocument(); break; case XmlPullParser.START_TAG: currentTag = xmlParser.getName(); this.handler.startTag(xmlParser.getName(), xmlParser .getDepth()); // 属性とか for (int i = 0; i < xmlParser.getAttributeCount(); i++) { this.handler.apperAttribute(xmlParser.getName(), xmlParser.getAttributeName(i), xmlParser .getAttributeValue(i), i); } break; case XmlPullParser.END_TAG: this.handler.endTag(xmlParser.getName(), xmlParser .getDepth()); break; case XmlPullParser.TEXT: if (xmlParser.isWhitespace() || xmlParser.isEmptyElementTag()) { this.handler.ignoreWhitespace(); } else { this.handler.apperText(currentTag, xmlParser .getText()); } break; } eventType = xmlParser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (XmlPullpaException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
■クライアント
XmlPullpaAdapterを継承した内部クラスをもっている
BR
public final static String BR = System.getProperty("line.separator");
package com.example.xmkfile; import java.io.StringReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.util.Xml; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.example.xml.helper.XmlPullpaAdapter; import com.example.xml.helper.XmlPullpaException; import com.example.xml.helper.XmlPullpaReader; public class XmlPullpaClient extends Activity { private Button btRead; private TextView txtXmlData; private MyPullpaAdapter handler; /** * XmlPullaAdapter実装クラス */ class MyPullpaAdapter extends XmlPullpaAdapter { @Override public void apperAttribute(String parent, String name, String value, int index) throws XmlPullpaException { txtXmlData.append("Attribute"); txtXmlData.append(Util.BR); txtXmlData.append(" tag=" + parent + " " + name + "=" + value + " index=" + index); txtXmlData.append(Util.BR); } @Override public void apperText(String parent, String value) throws XmlPullpaException { txtXmlData.append("Text"); txtXmlData.append(Util.BR); txtXmlData.append(" tag=" + parent + " value=" + value); txtXmlData.append(Util.BR); } @Override public void endDocument() throws XmlPullpaException { txtXmlData.append("End document"); txtXmlData.append(Util.BR); } @Override public void endTag(String name, int depth) throws XmlPullpaException { txtXmlData.append("End Tag"); txtXmlData.append(Util.BR); txtXmlData.append(" " + name + " depth=" + depth); txtXmlData.append(Util.BR); } @Override public void ignoreWhitespace() throws XmlPullpaException { txtXmlData.append("WhilteSpace"); txtXmlData.append(Util.BR); } @Override public void startDocument() throws XmlPullpaException { txtXmlData.append("Start Docment"); txtXmlData.append(Util.BR); } @Override public void startTag(String name, int depth) throws XmlPullpaException { txtXmlData.append("Start Tag"); txtXmlData.append(Util.BR); txtXmlData.append(" " + name + " depth=" + depth); txtXmlData.append(Util.BR); } } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.handler = new MyPullpaAdapter(); this.txtXmlData = (TextView) findViewById(R.id.TextViewXml); this.btRead = (Button) findViewById(R.id.ButtonRead); this.btRead.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // readXmlResources(); readXmlString(); } }); } /** * リソースから */ private void readXmlResources(){ Context context = getApplicationContext(); XmlPullpaReader reader = new XmlPullpaReader(); reader.setHandler(this.handler); reader.parse(context.getResources().getXml(R.xml.songs)); reader.read(); } /** * 文字列から */ private void readXmlString(){ XmlPullpaReader reader = new XmlPullpaReader(); reader.setHandler(this.handler); reader.parse("<hoge>sample</hoge>"); reader.read(); } }