トップ 差分 一覧 ソース 置換 検索 ヘルプ PDF RSS ログイン

JavaでXMLを扱う

概要

http://d.hatena.ne.jp/daisuke-m/20090113/1231853050
Javaには標準でXMLを扱う機能がある。
XMLを扱う機能は大きく2つある。

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


DOM

 読み込み

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
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();
    }
  }
}

 書き込み

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
32
33
34
35
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

 読み込み

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
32
33
34
35
36
37
38
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箇所にまとめてしまう。

 読み込み

1
2
      Tag tag = XMLUtil.toTag(new File("test.dat"));
      System.out.println(tag);

 書き込み

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     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

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
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.getRootTag();
  }
  
  public Tag parse(InputStream inputStream) throws SAXException, IOException {
    ParserHandler handler = new ParserHandler();
    parser.parse(inputStream, handler);
    return handler.getRootTag();
  }
  
  
  class ParserHandler extends DefaultHandler {
    protected Tag rootTag;
    protected Tag currentTag;
    // protected StringBuilder currentText;
    
    public ParserHandler() {
    }
    
    public Tag getRootTag() {
      return rootTag;
    }
    
    @Override
    public void startDocument() {
    }
    
    @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 (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();
    }
    
  }
}

[カテゴリ: プログラミング言語 > Java]



  • Hatenaブックマークに追加
  • livedoorクリップに追加
  • del.icio.usに追加
  • FC2ブックマークに追加

最終更新時間:2015年12月06日 19時40分03秒