Android 2.2からXPathが使えるようになったので使ってみた。使うまでがめんどいけど、XmlPullParserより使いやすいと思う。以下のXMLを対象にXPathを使ってみた。あまり詳しく書かないけど、少しだけ解説を載せたあと、ソースコードを載せる
<memo> <contents name="チラシの表">Hoge</text> <contents name="チラシの裏">Piyo</text> </memo>
XPathの例:
memoの1つ下のcontentsを取得する
/memo/contents
memoの1つ下の複数のcontentsの中から属性値が"チラシの表"のノードを取得する
/memo/contents[@name="チラシの表"]
memoの下の複数のcontentsの中から属性値が"チラシの表"の下のテキスト(Hoge)を取得する
/memo/contents[@name="チラシの表"]/text()
Javaで扱う場合:
Hogeを取得する例。XPathのevaluateを使う。最初の引数にXPathの文字列を、次の引数にXPathの基準となるノードを指定する。2つの引数のevaluateはStringを返す
String result = xpath.evaluate("/memo/contents[@name=\"チラシの裏\"]/text()", document);
複数のノードを返す例。XPathのevaluateを使うが、3つ目の引数にXPathConstants.NODESETを指定する。返ってくるのは3つ目の引数次第でObject型として返って来るのでキャストする。今回はNodeListを返してくる
NodeList result = (NodeList)xpath.evaluate("/memo/contents", document, XPathConstants.NODESET);
以下、ソースコード
package test.xpath; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import java.io.ByteArrayInputStream; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; public class XPathActivity extends Activity { private String xml; private TextView resultView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); resultView = new TextView(this); initXMLString(); xpathResult(); setContentView(resultView); } private void initXMLString(){ xml = "<memo>"; xml += "<contents name=\"チラシの表\">"; xml += "Hoge"; xml += "</contents>"; xml += "<contents name=\"チラシの裏\">"; xml += "Piyo"; xml += "</contents>"; xml += "</memo>"; } private void xpathResult(){ try{ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbFactory.newDocumentBuilder(); Document document = builder.parse(new ByteArrayInputStream(xml.getBytes())); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); String result = xpath.evaluate("/memo/contents[@name=\"チラシの表\"]/text()", document) + "\n"; result += xpath.evaluate("/memo/contents[@name=\"チラシの裏\"]/text()", document) + "\n"; //memoの1つしたの全てのcontentsノードを取り出す NodeList textList = (NodeList)xpath.evaluate("/memo/contents", document, XPathConstants.NODESET); //contentsノードを1つずつ取り出して更にXPathでアクセスする //ここではcontentsからの相対パスとなっている for(int i = 0; i < textList.getLength(); i++){ Node node = textList.item(i); //name属性を取り出す(属性名の前に@を付ける) result += xpath.evaluate("./@name", node) + ": "; //contentsの下のテキストを取り出す result += xpath.evaluate("./text()", node) + "\n"; } resultView.setText(result); }catch(Exception exception){ resultView.setText(exception.getClass().getName() + ": " + exception.getMessage()); } } }