RSSをDOMに格納して列挙するプログラムを作ります。
今となってはデータ構造が複雑なので余り使われませんね。
読み書きが必要ならJAXBを使った方が良いですし、読むだけならSAXが便利。
org.w3c.domは、JDKに標準で入っている、XMLをJavaのオブジェクトで表す為のデータ形式です。
XMLをDOMにマッピングするには以下のようにします。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse( 解析対象のXMLが得られるInputStream );
DOMをファイルに出力する時には、XSLTFilterInputStream?でやったように、Transformerを使います。
TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(); transformer.setOutputProperty("encoding", encode); transformer.setOutputProperty("indent", "yes"); DOMSource domSrc = new DOMSource( Documentオブジェクト ); OutputStream outStream = new FileOutputStream( "ファイル名" ); StreamResult result = new StreamResult(outStream ) transformer.transform(domSrc, result); outStream.flush(); outStream.close();
Document := ChildNode ChildNode := Node属性 AttributeNode* ChildNode* AttributeNode := Node属性 AttributeChildNode AttributeChildNode := Node属性 Node属性 := nodeName nodeValue nodeType nodeName := String型文字列 nodeValue := String型文字列 nodeType := short値(Nodeインタフェースで定義されている定数)
nodeNameとnodeValueは、nodeTypeによってそれぞれ以下のような値が格納されます。
nodeType | nodeName | nodeValue | どんなnode? |
Node.ELEMENT_NODE | タグ名 | null | タグ |
Node.ATTRIBUTE_NODE | 属性名 | 属性値 | タグの属性 |
Node.TEXT_NODE | #text | 属性値 | タグやタグの属性の値 |
Node.Node.COMMENT_NODE | #comment | コメント | コメント(<!-- … -->) |
<a href="http://foo.bar.com/" target="_cframe">リンク</a>
eq.
Document | +-ChildNode +-nodeName = a +-nodeValue = null +-nodeType = Node.ELEMENT_NODE +-AttributeNodes of this | | | +AttributeNode | | +-nodeName = href | | +-nodeValue = http://foo.bar.com/ | | +-nodeType = Node.ATTRIBUTE_NODE | | +-an AttributeChildNode of this | | | | | +-AttributeChildNode | | +-nodeName = #text | | +-nodeValue = http://foo.bar.com/ | | +-nodeType = Node.TEXT_NODE | | | +AttributeNode | +-nodeName = target | +-nodeValue = _cframe | +-nodeType = Node.ATTRIBUTE_NODE | +-an AttributeChildNode of this | | | +-AttributeChildNode | +-nodeName = #text | +-nodeValue = _cframe | +-nodeType = Node.TEXT_NODE | +-ChildNodes of this | +-ChildNode +-nodeName = #text +-nodeValue = リンク +-nodeType = Node.TEXT_NODE +-AttributeNodes of this = {null} +-ChildNodes of this = {null}
XML文書の改行やスペースもDOM構造に入ります
nodeName = #text nodeValue = (改行やスペース) nodeType = Node.TEXT_NODE
public final class RSSDOMReader { public static void main(String[] args) { final String xsltFilename = "C:/eclipse/workspace/RSS/feed-rss1.0.xsl"; final String xmlUrlString = "http://hondou.homedns.org/pukiwiki/pukiwiki.php?cmd=rss10"; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new XSLTFilterInputStream(xsltFilename, xmlUrlString)); Node node = doc.getFirstChild(); dumpElements(node, " "); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } public static void dumpElements(Node node, String indent) { System.out.println(indent + ".............................."); System.out.println(indent + "NAME: " + node.getNodeName()); System.out.println(indent + "VALUE: " + node.getNodeValue()); System.out.println( indent + "TYPE: " + getNodeTypeString(node.getNodeType())); System.out.println(indent + ".............................."); if (node.hasAttributes()) { System.out.println(indent + "-▽----------ATTRIBUTE----------"); NamedNodeMap nMap = node.getAttributes(); for (int cnt = 0; cnt < nMap.getLength(); cnt++) { dumpElements(nMap.item(cnt), indent + "\t"); } System.out.println(indent + "-△----------ATTRIBUTE----------"); } if (node.hasChildNodes()) { System.out.println(indent + "=▼=========CHILD NODE=========="); NodeList nList = node.getChildNodes(); for (int cnt = 0; cnt < nList.getLength(); cnt++) { dumpElements(nList.item(cnt), indent + "\t"); } System.out.println(indent + "=▲=========CHILD NODE=========="); } } public static String getNodeTypeString(short nodeType) { switch (nodeType) { case Node.ATTRIBUTE_NODE: return "ATTRIBUTE"; case Node.CDATA_SECTION_NODE: return "CDATA_SECTION"; case Node.COMMENT_NODE: return "COMMENT"; case Node.DOCUMENT_NODE: return "DOCUMENT"; case Node.DOCUMENT_FRAGMENT_NODE: return "DOCUMENT_FRAGMENT"; case Node.DOCUMENT_TYPE_NODE: return "DOCUMENT_TYPE_NODE"; case Node.ELEMENT_NODE: return "ELEMENT"; case Node.ENTITY_NODE: return "ENTITIY"; case Node.ENTITY_REFERENCE_NODE: return "ENTITY_REFERENCE"; case Node.NOTATION_NODE: return "NOTATION"; case Node.PROCESSING_INSTRUCTION_NODE: return "PROCESSING_INSTRUCTION"; case Node.TEXT_NODE: return "TEXT"; } return "UNKNOWN_NODE_TYPE"; } }