トップ 一覧 置換 検索 ヘルプ RSS ログイン

JavaでXMLを扱うの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!概要
http://d.hatena.ne.jp/daisuke-m/20090113/1231853050
Javaには標準でXMLを扱う機能がある。
XMLを扱う機能は大きく2つある。

:DOM:メモリに全て読み込んでツリーを生成する。各ノードにランダム・アクセスが可能。
:SAX:XMLを読み込みながらイベントを発生させる。大きなXMLの読み込みに向いている。


!!!DOM
!!読み込み
{{code Java,
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

public class test {
  public static void main(String param[]){
    try{
      DocumentBuilder bld = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document doc = bld.parse(new File("test.xml"));
      Element element = doc.getDocumentElement();
      printNode(element);
    } catch (Exception e){
      System.err.println(e);
    }
  }
  
  public static void printNode(Node node) {
    Node child = node.getFirstChild();
    while(child != null) {
      System.out.println(child.getNodeName() + " Text = " + child.getNodeValue());
      printNode(child);
      child = child.getNextSibling();
    }
  }
}
}}

!!書き込み
{{code Java,
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class test3 {
  public static void main(String param[]){
    try{
      DocumentBuilder bld = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document doc = bld.parse(new File("test.dat"));
      Element element = doc.getDocumentElement();
      
      
      FileOutputStream os = new FileOutputStream("out.xml");
      StreamResult result = new StreamResult(os);
      
      TransformerFactory factory = TransformerFactory.newInstance();
      Transformer transformer = factory.newTransformer();
      
      // エンコード:UTF-8、インデントありを指定
      transformer.setOutputProperty("encoding", "UTF-8");
      transformer.setOutputProperty("indent", "yes");
      
      DOMSource source = new DOMSource(doc);
      
      transformer.transform(source, result);
      
    } catch (Exception e){
      System.err.println(e);
    }
  }
}

}}

!!!SAX
!!読み込み
{{code Java,
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;


public class test2 {
  public static void main(String param[]){
    try{
      // SAXパーサーファクトリを生成
      SAXParserFactory spfactory = SAXParserFactory.newInstance();
      // SAXパーサーを生成
      SAXParser parser = spfactory.newSAXParser();
      // XMLファイルを指定されたデフォルトハンドラーで処理します
      DefaultHandler handler = new DefaultHandler() {
        @Override
        public void characters(char[] ch, int start, int length) {
          System.out.println("text = " + new String(ch, start, length) + ":");
        }
        
        @Override
        public void startElement(String uri,
          String localName,
          String qName,
          Attributes attributes)
        {
          System.out.println("element " + qName);
        }
        
      };
      parser.parse(new File("test.xml"), handler);
      
    } catch (Exception e){
      System.err.println(e);
    }
  }
}

}}

!!書き込み
基本的に通常のファイルを書き込むように、ファイルを作成する。

!!!自作ユーティリティ
簡単なユーティリティを作成する。
テキストは1箇所にまとめてしまう。

!!読み込み
{{code Java,
      Tag tag = XMLUtil.toTag(new File("test.dat"));
      System.out.println(tag);
}}

!!書き込み
{{code Java,
     Tag tag = new Tag("root");
      tag.addTag(new Tag("a"));
      tag.addTag(new Tag("b"));
      tag.addTag(new Tag("c"));
      tag.addTag(new Tag("a"));
      
      tag.get("a", 0).addTag(new Tag("aa"));
      tag.get("a", 1).addTag(new Tag("aa"));
      tag.get("b", 0).addTag(new Tag("bb"));
      tag.get("b", 0).addTag(new Tag("bb"));
      tag.get("b", 0).get("bb",0).addTag(new Tag("b"));
      tag.get("b", 0).get("bb",0).addTag(new Tag("b"));
      tag.get("b", 0).get("bb",1).addTag(new Tag("b"));
      tag.get("b", 0).get("bb",1).addTag(new Tag("b"));
      tag.get("b", 0).get("bb",0).get("b",0).setText("b");
      tag.get("b", 0).get("bb",0).get("b",1).setText("b2");
      tag.get("b", 0).get("bb",1).get("b",0).setText("b2_1");
      tag.get("b", 0).get("bb",1).get("b",1).setText("b2_2");
      
      Element element = XMLUtil.toElement(tag);
      System.out.println(XMLUtil.toString(element));
      
}}


!!XMLUtil
{{code Java,
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;


public class XMLUtil {
  
  protected static final String ln = System.getProperty("line.separator");
  
  public static Tag toTag(File xmlFile) throws SAXException, IOException, ParserConfigurationException {
    XMLParser parser = new XMLParser();
    return parser.parse(xmlFile);
  }
  
  public static Tag toTag(InputStream inputStream) throws SAXException, IOException, ParserConfigurationException {
    XMLParser parser = new XMLParser();
    return parser.parse(inputStream);
  }
  
  public static Element toElement(Tag tag) throws ParserConfigurationException {
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.newDocument();
    Element element = doc.createElement(tag.getName());
    
    copyToElement(doc, tag, element);
    return element;
  }
  
  protected static void copyToElement(Document doc, Tag tag, Element element) {
    // 属性の設定
    Map<String, String> attrs = tag.getAttributes();
    for(String key: attrs.keySet()) {
      element.setAttribute(key, attrs.get(key));
    }
    // System.out.println(tag.getText());
    element.appendChild(doc.createTextNode(tag.getText()));
    
    Map<String, List<Tag>> tagListMap = tag.getChildren();
    for(String key: tagListMap.keySet()) {
      for(Tag childTag: tagListMap.get(key)) {
        Element childElement = doc.createElement(childTag.getName());
        // element.appendChild(doc.createTextNode(ln));
        element.appendChild(childElement);
        copyToElement(doc, childTag, childElement);
      }
    }
  }
  
  public static void writeElement(Node node, File file)  throws TransformerConfigurationException, TransformerException {
    writeElement(node, new StreamResult(file));
  }
  
  public static void writeElement(Node node, Writer writer)  throws TransformerConfigurationException, TransformerException {
    writeElement(node, new StreamResult(writer));
  }
  
  public static void writeElement(Node node, StreamResult result) throws TransformerConfigurationException, TransformerException {
    
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    
    // エンコード:UTF-8、インデントありを指定
    transformer.setOutputProperty("encoding", "UTF-8");
    transformer.setOutputProperty("indent", "yes");
    
    DOMSource source = new DOMSource(node);
    
    transformer.transform(source, result);
  }
  
  public static String toString(Node node)  throws TransformerConfigurationException, TransformerException {
    StringWriter sw = new StringWriter();
    writeElement(node, sw);
    return sw.toString();
  }
  
  protected static String getText(Node node) {
    switch (node.getNodeType()) {
    case Node.ELEMENT_NODE:
      return node.getNodeName();
      
    case Node.TEXT_NODE:
      return node.getNodeValue();
      
    default:
      return node.getNodeName();
    }
  }
}

class Tag {
  // public static final String ATTRIBUTES = "@Attributes";
  // public static final String TEXT = "@Text";
  protected Map<String, List<Tag>> map;
  protected Map<String, String> attributes;
  protected String name; 
  protected StringBuilder textBuilder;
  protected Tag parent;
  
  public Tag(String name) {
    map = new HashMap<>();
    attributes = new HashMap<>();
    this.name = name;
    this.textBuilder = new StringBuilder();
    this.parent = null;
  }
  
  public Map<String, List<Tag>> getChildren() {
    return map;
  }
  
  public List<Tag> get(String qName) {
    return map.get(qName);
  }
  
  public Tag get(String qName, int index) {
    return map.get(qName).get(index);
  }
  
  public String getName() {
    return this.name;
  }
  
  public String getText() {
    return this.textBuilder.toString();
  }
  
  public void setText(String text) {
    this.textBuilder.delete(0, textBuilder.length());
    this.textBuilder.append(text);
  }
  
  public void addText(String text) {
    this.textBuilder.append(text);
  }
  
  public Tag getParent() {
    return this.parent;
  }
  
  private void setParent(Tag parent) {
    this.parent = parent;
  }
  
  public Map<String, String> getAttributes() {
    return this.attributes;
  }
  
  public void setAttributes(Attributes attrs) {
    
    for(int i = 0; i < attrs.getLength(); i++) {
      String qName = attrs.getQName(i);
      String value = attrs.getValue(i);
      attributes.put(qName, value);
    }
  }
  
  public void addTag(Tag child) {
    String key = child.getName();
    if (!map.containsKey(key)) {
      map.put(key, new ArrayList<Tag>());
    }
    
    List<Tag> list = map.get(key);
    list.add(child);
    child.setParent(this);
  }
  
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    dump(this, 0, sb, 0);
    
    return sb.toString();
  }
  
  protected void dump(Tag tag, int level, StringBuilder sb, int index) {
    char[] spaces = new char[level];
    Arrays.fill(spaces, ' ');
    String indent = new String(spaces);
    String ln = System.getProperty("line.separator");
    
    sb.append(tag.getName()).append("[").append(index).append("]").append(ln);
    sb.append(indent).append("  ").append("attributes = ").append(tag.getAttributes().toString()).append(ln);
    
    
    String text = tag.getText().replaceAll("[\\r\\n]","").trim();
    if (!"".equals(text)) {
      sb.append(indent).append("  ").append("Text = ").append(text).append(ln);
    }
    
    Map<String, List<Tag>> map = tag.map;
    for(String key: map.keySet()) {
      // sb.append(indent).append(key).append(ln);
      List<Tag> list = map.get(key);
      
      for(int i = 0; i < list.size(); i++) {
        sb.append(indent).append("  ");
        Tag child = list.get(i);
        // sb.append(indent).append(child.getName());
        // sb.append("[").append(i).append("]");
        dump(child, level + 2, sb, i);
      }
    }
  }
  
}

class XMLParser {
  protected SAXParserFactory factory;
  protected SAXParser parser;
  protected ParserHandler handler;
  
  public XMLParser() throws ParserConfigurationException, SAXException {
    // SAXパーサーファクトリを生成
    factory = SAXParserFactory.newInstance();
    // SAXパーサーを生成
    parser = factory.newSAXParser();
  }
  
  public Tag parse(File file) throws SAXException, IOException {
    ParserHandler handler = new ParserHandler();
    parser.parse(file, handler);
    return handler.getTag();
    return handler.getRootTag();
  }
  
  public Tag parse(InputStream inputStream) throws SAXException, IOException {
    ParserHandler handler = new ParserHandler();
    parser.parse(inputStream, handler);
    return handler.getTag();
    return handler.getRootTag();
  }
  
  
  class ParserHandler extends DefaultHandler {
    protected Tag tag;
    protected Tag rootTag;
    protected Tag currentTag;
    // protected StringBuilder currentText;
    
    public ParserHandler() {
      // tag = new Tag("root");
      // currentText = new StringBuilder();
    }
    
    public Tag getTag() {
      return tag;
    public Tag getRootTag() {
      return rootTag;
    }
    
    @Override
    public void startDocument() {
      // currentTag = tag;
    }
    
    @Override
    public void characters(char[] ch, int start, int length) {
      // currentText.append(new String(ch, start, length));
      // currentTag.addText("{");
      currentTag.addText(new String(ch, start, length));
      // currentTag.addText("}");
    }
    
    @Override
    public void startElement(String uri,
      String localName,
      String qName,
      Attributes attributes)
    {
      Tag child = new Tag(qName);
      // currentText.delete(0, currentText.length());
      child.setAttributes(attributes);
      // // System.out.println(qName + " : " + localName);
      
      // ルートのタグを生成
      if (currentTag == null) {
        tag = child;
      // ルートのタグの設定
      if (rootTag == null) {
        rootTag = child;
      } else {
        currentTag.addTag(child);
      }
      currentTag = child;
    }
    
    @Override
    public void endElement(String uri,
      String localName,
      String qName) 
    {
      // currentTag.setText(currentText.toString());
      // currentText.delete(0, currentText.length());
      currentTag = currentTag.getParent();
    }
    
  }
}

}}

{{category2 プログラミング言語,Java}}