スポンサーサイト:岡山の専門学校ビーマックス ITスペシャリスト学科のBe-Blog


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

XML文書におけるJavaとRubyの比較:岡山の専門学校ビーマックス ITスペシャリスト学科のBe-Blog


twitterの方に書いたネタなんだけど、
あっちだと、タイムラインでどんどん流れていくので、
せっかくがんばってソース書いたし、こっちにも残しておく。

さて、なんの話かと言うと、
XML文書から、特定の条件を満たすデータを抽出して表示するプログラムを、
Java言語とRuby言語で書いた場合、どのくらいソースコードが違うのか、
という話であります。

まず、データ元のXML文書はこちらであります。

addressbook.xml
<?xml version="1.0" encoding="UTF-8"?>
<addressbook>
<person>
<name>マックス太郎</name>
<address>
<prefecture>岡山県</prefecture>
<city>岡山市北区</city>
<block>島田本町1-6-12</block>
</address>
</person>
<person>
<name>マックス次郎</name>
<address>
<prefecture>岡山県</prefecture>
<city>倉敷市</city>
<block>老松町xxxxx</block>
</address>
</person>
<person>
<name>マックス三郎</name>
<address>
<prefecture>岡山県</prefecture>
<town>久米郡美咲町</town>
<block>柵原xxxxx</block>
</address>
</person>
<person>
<name>マックス四朗</name>
<address>
<prefecture>広島県</prefecture>
<town>世羅郡世羅町</town>
<block>西上原xxxxx</block>
</address>
</person>
<person>
<name>マックス五郎</name>
<address>
<prefecture>岡山県</prefecture>
<city>岡山市北区</city>
<block>駅元町5-11</block>
</address>
</person>
</addressbook>


このデータから、住所が「岡山市北区」になっているのは、
マックス太郎
マックス五郎

の二人ですね。

では、条件に合うデータをXML文書から抽出するプログラムを紹介しましょう。
ます、XPathを使用しない場合のJava言語のソースから。


JavaDomSample.java
package xmldomtest;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
import java.util.ArrayList;

public class JavaDomSample {
public static void main(String[] args) {
String name = null;
ArrayList<String> resultList = new ArrayList<String>();
String[] result = null;
try{
File xml = new File("addressbook.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xml);
NodeList persons = doc.getElementsByTagName("person");
for(int i=0; i<persons.getLength(); i++){
NodeList ch = persons.item(i).getChildNodes();
for(int j=0; j<ch.getLength(); j++){
Node n = ch.item(j);
if(n.getNodeType()==Node.ELEMENT_NODE){
if(n.getNodeName().equals("name")){
name = n.getFirstChild().getNodeValue();
}
if(n.getNodeName().equals("address")){
NodeList ch2 = n.getChildNodes();
for(int k=0; k<ch2.getLength(); k++){
Node n2 = ch2.item(k);
if(n2.getNodeType()==Node.ELEMENT_NODE){
if(n2.getNodeName().equals("city")){
if(n2.getFirstChild().getNodeValue().equals("岡山市北区")){
resultList.add(name);
}
}
}
}
}
}
}
}
result = resultList.toArray(new String[resultList.size()]);
}catch(Exception e){
e.printStackTrace();
result = null;
}
for(String s:result){
System.out.println(s);
}
}
}

とっても長くてややこしいので、何やってるのか説明しろと言われたら、ちょっと嫌なソースです。
これ見てすぐに内容を理解できる人がいたら、すごいと思います。


次に、XPathを利用して検索する場合について。
XPathというのは、XML文書の階層構造を、ファイル-ディレクトリの階層構造のように見立てて、要素をパスで表すものです。
このXPathの便利な処は、[ ]内に抽出条件を記述できること。
今回場合、目的のデータを抽出するためのXPath式は、
/addressbook/person/name[../address/city/text()='岡山市北区']/text()
です。

JavaXPathSample.java
package xmlxpathtest;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;

public class JavaXPathSample {
public static void main(String[] args) {
String[] result = null;
try{
File xml = new File("addressbook.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xml);
XPathFactory xfact = XPathFactory.newInstance();
XPath xp = xfact.newXPath();
XPathExpression xpex = xp.compile("/addressbook/person/name[../address/city/text()='岡山市北区']/text()");
Object res = xpex.evaluate(doc, XPathConstants.NODESET);
NodeList resultList = (NodeList)res;
result = new String[resultList.getLength()];
for(int i=0; i result[i] = resultList.item(i).getNodeValue();
}
}catch(Exception e){
e.printStackTrace();
result = null;
}
for(String s:result){
System.out.println(s);
}
}
}

先ほどよりは、短いソースになりましたね。
でも、XPath式で抽出を行うまでに必要な準備が多く、しかもそれらが何の為のコードなのか、よくわかりません。
何の参考書とかも見ずにソースを書きあげるのは、至難のわざですね。


さて、最後にRuby言語で記述した場合です。
Rubyに標準でついてくるXMLライブラリは、XPathが使えるので、先のXPath式を利用して、データを抽出しましょう。

RubyRexmlSample.rb
require 'rexml/document'
include 'REXML'

file = open("addressbook.xml")
doc = Document.new file
result = XPath.match doc, "/addressbook/person/name[../address/city/text()='岡山市北区']/text()"
result.each do |name|
puts name
end

いやー、短くて簡潔ですね。result配列に抽出データを格納するまで、3行!
これぞ、Rubyの本領発揮ですね。
ちなみに、各ソースの緑色のコードが、抽出データが格納されたタイミングになります。


同じことをするのでも、ソースコードが短くて済むほうが、
開発にかかる時間も短くてすむので、開発コストを安く抑えることができます。
今、岡山県でもRubyでシステムを開発しようという機運が高まっているのも、
そういったメリットがあるためなんですね。

長文を最後まで読んでくれてありがとう。

by ホーリー

にほんブログ村 教育ブログ 専門学校教育へ
にほんブログ村
スポンサーサイト

コメントの投稿

非公開コメント

- カレンダー -
- facebook -
天気予報

-天気予報コム- -FC2-
クラウド ガール | MSDN 技術解説コミック
クラウド ガール | MSDN 技術解説コミック
カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
最近の記事
カテゴリー
FC2カウンター
リンク
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。