!!!概要 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 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> 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> map; protected Map 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> getChildren() { return map; } public List 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 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()); } List 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> map = tag.map; for(String key: map.keySet()) { // sb.append(indent).append(key).append(ln); List 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(); } } } }} {{category2 プログラミング言語,Java}}