JavaでXMLをDOM操作するためには下記クラスを使用します。
javax.xml.parsers.DocumentBuilder
- XMLドキュメントからDOM Documentインスタンスを取得するAPI
javax.xml.parsers.DocumentBuilderFactory
- アプリケーションでXMLドキュメントからDOMオブジェクト・ツリーを生成するパーサーを取得できるファクトリAPI
XMLファイル
以下のXMLを読み込み、取得した要素をコンソールへ出力してます。
|
1 2 3 4 5 6 7 |
<?xml version="1.0" encoding="UTF-8"?> <product name="商品" company="A社"> <goods name="時計" /> <goods name="スマホ" /> <goods name="パソコン" /> <goods name="エアコン" /> </product> |
Java:DOMでXMLを読み込むサンプルコード
|
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 |
import java.io.FileInputStream; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.XMLConstants; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class XmlParseEnhanced { public static void main(String[] args) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { // セキュリティ設定 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // 名前空間対応 dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); try (InputStream in = new FileInputStream("SampleXml.xml")) { Document doc = db.parse(in); doc.getDocumentElement().normalize(); XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); // ルート属性読み込み Element root = doc.getDocumentElement(); System.out.println("種類:" + root.getAttribute("name")); System.out.println("会社名:" + root.getAttribute("company")); // goods 要素を XPath で抽出 NodeList goodsList = (NodeList) xpath.evaluate("/product/goods", doc, XPathConstants.NODESET); for (int i = 0; i < goodsList.getLength(); i++) { Element goods = (Element) goodsList.item(i); System.out.println("商品名:" + goods.getAttribute("name")); } } } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) { e.printStackTrace(); // 実運用ではログ記録・ユーザ通知・例外再スローなども検討 } } } |
コンソール(実行結果)
|
1 2 3 4 5 6 |
種類:商品 会社名:A社 商品名:時計 商品名:スマホ 商品名:パソコン 商品名:エアコン |
✅ XML DOM解析に関する補足
上記コードでは基本的な DOM パーサ処理を紹介しましたが、実務で XML を扱う際には、以下の点も意識しておくとより堅牢で拡張性の高い実装になります。
■ セキュリティ設定(XXE対策)
外部エンティティ参照を悪用した XXE(XML External Entity)攻撃を防ぐため、DocumentBuilderFactory 生成時に外部参照を無効化する設定が推奨されます。
特に外部入力 XML を処理する場合は必須です。
■ 文字コードとファイル読み込み
XML に encoding="UTF-8" が記載されていても、実際のファイルの文字コードと一致しないケースがあります。
必要に応じて InputStreamReader("UTF-8") を使うなど、明示的にエンコーディングを指定しましょう。
■ ノード取得方法の選択
DOMでは getChildNodes() で全ノードを走査できますが、要素のみを対象にしたい場合は:
-
getElementsByTagName() -
または XPath (
/root/child)
を使うとコードが簡潔になります。
■ 大規模XMLではDOMに注意
DOM は XML を全てメモリ上に展開するため、大きい XML(数十MB〜)を扱うとメモリ負荷が高くなります。
大容量データの場合は、SAX や StAX といったストリーミング解析方式も検討してください。
■ XML → オブジェクト変換
XMLデータを業務ロジックで扱う場合、DOMノードを直接扱うよりも、
専用クラス(POJO)にマッピングして処理すると保守性が高まります。
💡 まとめ
XML はシステム間連携などで今でも多く利用されています。
DOMは直感的で扱いやすい反面、セキュリティやパフォーマンス面での注意が必要です。
小〜中規模の XML 解析に便利な手法なので、ケースに応じて SAX / XPath と使い分けながら活用してください。
