JSON みたいに手軽に XML を使いたくて、似たような感じの XPath というのを試してみた。

ソースコード


import java.io.*;
import java.net.*;
import java.util.*;
import javax.mail.internet.*; // mailapi.jar from JavaMail API 1.4: http://java.sun.com/products/javamail/
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.*;
 
public class Rest {
 
  public static void main(String[] args) throws Exception {
    
    // Yahoo!デベロッパーネットワーク - Yahoo!検索 - 関連検索ワード
    // http://developer.yahoo.co.jp/search/webunit/V1/webunitSearch.html 
    GetRequest req = new GetRequest("http://api.search.yahoo.co.jp/AssistSearchService/V1/webunitSearch");
    req.set("appid", "YahooDemo");
    req.set("query", "猫");
    req.set("results", "10");
    req.set("start", "1");
    
    Rest rest = new Rest();
    XmlResponse res = rest.get(req);
    
    // XPath利用サンプル
    int length = res.getLength("ResultSet/Result");
    for(int i=0; i<length; i++){
      String s = res.getString("ResultSet/Result[" + (i + 1) + "]");
      System.out.println(s);
    }
 
    // もっと複雑な XML 文書になったらヤバげ
    // XPath xpath = res.getXPath();
    // Document doc = res.getXMLDocument();
    // で対処。
    //
    // でも、できれば XPath 使いたくないので、
    // JSON みたいに簡単に扱えないかなぁ……
    //
    // IBM XML から JSON を生成し、Ajax で使う - Japan
    // http://www-06.ibm.com/jp/developerworks/web/library/x-xml2json/index.shtml
    //
    // とか参考になるかも。
    //
  }
  
  public Rest(){
  }
 
  // URL から XML 文書情報を取得
  public XmlResponse get(GetRequest req) throws Exception {
    String url = req.getURL();
    System.out.println("url=" + url);
 
    // 状況に応じて使い分け?
    
    // パターン1: DocumentBuilder が 直接処理
    //Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url);
    //return new XmlResponse(doc);
    
    // パターン1: わざわざ URLConnection を使って処理
    String content = getContent(new URL(url));
    System.out.println(content);
    StringReader sr = new StringReader(content);
    InputSource is = new InputSource(sr);
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
    return new XmlResponse(doc);
  }
 
  // URLからコンテンツ(HTML/XMLページの文字列)を取得
  private static String getContent(URL url) throws Exception{
    
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setRequestMethod("GET");
    
    // ex. String ct = "text/xml; charset=\"utf-8\"";
    String ct = con.getContentType();
    String charset = "UTF-8"; // Content Type が無ければ UTF-8 KIMEUCHI
    if(ct != null){
      // JavaMail なクラス ContentType
      // Java SE にあればいいのに……
      String cs = new ContentType(ct).getParameter("charset"); // fixed at 20070520
      if(cs != null){
        charset = cs;
      }
      System.out.println("charset=" + charset);
    }
 
    InputStream is = con.getInputStream();
    InputStreamReader isr = new InputStreamReader(is, charset);
    BufferedReader br = new BufferedReader(isr);
    StringBuffer buf = new StringBuffer();
    String s;
    while ((s = br.readLine()) != null) {
      buf.append(s);
      buf.append("\r\n"); // 改行コードKIMEUCHI
    }
 
    br.close();
    con.disconnect();
    
    return buf.toString();
  }
  
  /**
   * get method for http.
   */
  public static class GetRequest{
 
    private final String baseurl;
    private final Properties params = new Properties();
 
    private String encoding = "UTF-8";
 
    public GetRequest(String baseurl){
      this.baseurl = baseurl;
    }
    
    public void setEncoding(String encoding){
      this.encoding = encoding;
    }
 
    public void set(Properties params){
      params.putAll(params);
    }
 
    public void set(String key, String value){
      params.setProperty(key, value);
    }
 
    // HTTP PATH INFO なパラメータは考慮しない
    public String getURL() throws Exception {
 
      StringBuffer buf = new StringBuffer();
      buf.append(baseurl);
      if(!baseurl.endsWith("?") && params.size() > 0){ // fixed at 20070520
        buf.append("?");
      }
      for (Enumeration names = params.propertyNames(); names.hasMoreElements();) {
        String key = (String) names.nextElement();
        String val = params.getProperty(key);
        buf.append(key);
        buf.append("=");
        if(encoding != null){
          buf.append(URLEncoder.encode(val, encoding));
        }else{
          buf.append(val);
        }
        buf.append("&");
      }
      if (buf.charAt(buf.length() - 1) == '&') {
        buf.deleteCharAt(buf.length() - 1);
      }
  
      return buf.toString();
    }
  }
 
  /**
   * xml response for http.
   */
  public static class XmlResponse{
    
    private final Document doc;
    private final XPath xpath;
    
    XmlResponse(Document doc){
      this.doc = doc;
      this.xpath = XPathFactory.newInstance().newXPath();
    }
 
    public int getLength(String expression) throws XPathExpressionException{
      // XPath 利用サンプル
      NodeList nodelist = (NodeList)xpath.evaluate(expression, doc, XPathConstants.NODESET);
      if(nodelist != null){
        return nodelist.getLength();
      }else{
        return 0;
      }
    }
 
    public String getString(String expression) throws XPathExpressionException{
      // XPath 利用サンプル
      return xpath.evaluate(expression, doc);
    }
 
    public XPath getXPath(){
      return xpath;
    }
 
    public Document getXMLDocument(){
      return doc;
    }
  }
 
}

実行結果


url=http://api.search.yahoo.co.jp/AssistSearchService/V1/webunitSearch?results=10&appid=YahooDemo&query=%E7%8C%AB&start=1
charset=utf-8
<?xml version="1.0" encoding="UTF-8" ?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:jp:srchunit" xsi:schemaLocation="urn:yahoo:jp:srchunit http://api.search.yahoo.co.jp/AssistSearchService/V1/WebUnitSearchResponse.xsd" totalResultsReturned="10" totalResultsAvailable="100" firstResultPosition="1">
<Result>ペット 猫</Result>
<Result>猫 里親</Result>
<Result>犬 猫</Result>
<Result>猫 病気</Result>
<Result>猫 画像</Result>
<Result>猫 写真</Result>
<Result>猫 壁紙</Result>
<Result>猫 ブログ</Result>
<Result>猫 イラスト</Result>
<Result>猫 種類</Result>
</ResultSet>
<!-- pls338.search.tnz.yahoo.co.jp uncompressed/chunked Fri Jan  5 21:20:19 JST 2007 -->
<!-- ws1.search.bbt.yahoo.co.jp uncompressed/chunked Fri Jan  5 21:20:19 JST 2007 -->
 
ペット 猫
猫 里親
犬 猫
猫 病気
猫 画像
猫 写真
猫 壁紙
猫 ブログ
猫 イラスト
猫 種類

Ref.

tags: zlashdot Java Java

Posted by NI-Lab. (@nilab)