employee1.xmlは従業員情報を記録したファイルです。このemployee1.xmlは外部エンティティとしてemployee2.xmlとemployee3.xmlを参照しています。
employee1.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE employees [
<!ENTITY employee2 SYSTEM "./employee2.xml">
<!ENTITY employee3 SYSTEM "./employee3.xml">
]>
<employees>
<employee>佐藤一郎</employee>
<employee>鈴木一郎</employee>
&employee2;
&employee3;
</employees>
employee2.xml
<employee>高橋二郎</employee>
<employee>田中二郎</employee>
employee3.xml
<employee>伊藤三郎</employee>
<employee>渡辺三郎</employee>
このemployee1.xmlファイルをパースして、従業員の名前一覧を取得しつつ、その従業員がどのファイルに記載されているのかを知りたいとします。たとえば「高橋二郎」であればemployee2.xml、「渡辺三郎」であればemployee3.xmlに記載されているという情報をとりたいわけです。どのように実現すればよいでしょうか?
結論を述べると、ノードや要素がどのファイルに記載されているかを取得したい場合、NodeクラスのgetBaseURIメソッドを利用します。
String xmlPath = "D:\\tmp\\employee1.xml";
try (InputStream is = Files.newInputStream(Paths.get(xmlPath))) {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is, xmlPath);
NodeList childNodes = document.getDocumentElement().getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) childNode;
String textContent = element.getTextContent();
String baseURI = element.getBaseURI();
System.out.printf("textContent=%s, baseURI=%s%n", textContent, baseURI);
}
}
} catch (IOException | SAXException | ParserConfigurationException e) {
e.printStackTrace();
}
このプログラムを実行すると、以下のような結果が得られます。
textContent=佐藤一郎, baseURI=file:///D:/tmp/employee1.xml
textContent=鈴木一郎, baseURI=file:///D:/tmp/employee1.xml
textContent=高橋二郎, baseURI=file:///D:/tmp/employee2.xml
textContent=田中二郎, baseURI=file:///D:/tmp/employee2.xml
textContent=伊藤三郎, baseURI=file:///D:/tmp/employee3.xml
textContent=渡辺三郎, baseURI=file:///D:/tmp/employee3.xml
NodeクラスのgetBaseURIメソッドにより、ノードや要素がどのファイルに記載されているのかを取得できることが確認できました。
環境情報
D:\>java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
D:\>javac -version
javac 17.0.3