2.DOMでドキュメントを走査する。(2001.06.03)
DOM APIを使ってXMLをファイルへ出力してみます。Javaを使うとこれはいとも簡単に出来ます。ルートにエレメントを張り付けて、最後はシリアライズする事でXMLを出力することになります。
import java.io.*; import org.apache.xerces.parsers.*; import org.apache.xerces.dom.*; import org.apache.xml.serialize.*; import org.xml.sax.*; import org.w3c.dom.*; class Bruckner { public static void main(String args[]) { try { Document doc = new DocumentImpl(); Element newElement = doc.createElement("Bruckner"); newElement.setAttribute("version","1.0"); Element mElement = doc.createElement("Symphony"); newElement.appendChild(mElement); Element No8Element = doc.createElement("No8"); mElement.appendChild(No8Element); Element ConElement = doc.createElement("Conductor"); No8Element.appendChild(ConElement); Text ConText = doc.createTextNode("BOHM"); ConElement.appendChild(ConText); Element OchElement = doc.createElement("Orchestra"); No8Element.appendChild(OchElement); Text No8_vText = doc.createTextNode("VPO"); OchElement.appendChild(No8_vText); Element No9Element = doc.createElement("No9"); mElement.appendChild(No9Element); Element Con2Element = doc.createElement("Conductor"); No9Element.appendChild(Con2Element); Text Con2Text = doc.createTextNode("朝比奈隆"); Con2Element.appendChild(Con2Text); Element Och2Element = doc.createElement("Orchestra"); No9Element.appendChild(Och2Element); Text placeText = doc.createTextNode("大阪フィル"); Och2Element.appendChild(placeText); doc.appendChild(newElement); OutputFormat of = new OutputFormat(doc); of.setEncoding("Shift_JIS"); FileOutputStream fos = new FileOutputStream("out.xml"); OutputStreamWriter osw = new OutputStreamWriter(fos,"Shift_JIS"); Writer out = new PrintWriter(osw); of.setIndenting(true); //**** インデントの設定 XMLSerializer xs = new XMLSerializer(out,of); xs.asDOMSerializer(); xs.serialize(doc.getDocumentElement()); out.close(); } catch(Exception e){ e.printStackTrace(); } } }パーサはXercesを使いましたが、テキストノードの漢字が下のように出力されました。IE5で表示してみるとちゃんと漢字で表示されます。
<?xml version="1.0" encoding="Shift_JIS"?>
<Bruckner version="1.0">
<Symphony>
<No8>
<Conductor>BOHM</Conductor>
<Orchestra>VPO</Orchestra>
</No8>
<No9>
<Conductor>朝比奈隆</Conductor>
<Orchestra>大阪フィル</Orchestra>
</No9>
</Symphony>
</Bruckner>
さてDOMを使ってドキュメントを走査してみます。各参考書を見ると皆再帰法によって処理を進めています。DOMはそもそもXMLをメモリー上にツリー展開するものですが、ツリーの枝がどこまで枝分かれしているのかは展開するまで判らないので、再帰的にその形状を追っていくというところです。次のソースを実行すると読み取ったXMLのエレメントとアトリビュートを全て表示してくれます。(パーサはapacheのXercesを使いました。)
import java.io.*; import org.w3c.dom.*; import javax.xml.parsers.*; public class testDOM { public static void main(String args[]) { Document document = null; if(args.length == 0) { System.out.println("ファイル名を指定して下さい"); } try { DocumentBuilder docBuild = DocumentBuilderFactory.newInstance().newDocumentBuilder(); document = docBuild.parse(new File(args[0])); } catch(Exception e) { e.printStackTrace(); } Node node = document.getDocumentElement(); ProcessNodeRecursively(node); } static public void ProcessNodeRecursively(Node node){ if(node.getNodeValue()==null){ System.out.println("Name = " + node.getNodeName()); } else { if(node.getNodeValue().trim().length()!=0){ System.out.println("Value = " + node.getNodeValue()); } } NamedNodeMap attrs = node.getAttributes(); if(attrs != null){ for (int i = 0; i < attrs.getLength(); i++){ Attr attr = (Attr)attrs.item(i); System.out.println(" " + attr.getNodeName() + "=\"" + attr.getNodeValue() + '"'); } } for(Node child = node.getFirstChild(); child!=null; child= child.getNextSibling()){ ProcessNodeRecursively(child); } }
XMLが文法的に正しいか、DTDの記載通りになっているか調べるにはパーサを使います。パーサはIBMやOracle社提供のものなど既に幾つも公開されていて容易に利用することが可能です。試しに標準入力から読み込んだXMLをパースする最も単純なプログラムを組んでいます。言語は勿論JavaでパーサはIBM社のXML4Jを使います。
import org.w3c.dom.Document;
import com.ibm.xml.parser.Parser;
import java.io.FileInputStream;
public class xmlParse {
public static void main(String[] argv) {
if (argv.length != 1) {
System.err.println("Bad filename!!");
System.exit(1);
} try {
FileInputStream fis = new FileInputStream(argv[0]);
Parser parser = new Parser(argv[0]);
Document doc = parser.readStream(fis);
if (parser.getNumberOfErrors() < 0) {
System.exit(1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}ところでIE5ではXMLの表示が可能であり、当然文法的なチェックをします。ところがDTDとのチェックは行なわないようです。バグだと思ったのですが、マイクロソフト社の言い分では仕様との話です。
http://support.microsoft.com/support/kb/articles/Q239/5/40.ASP?LNG=ENG&SA=PER&FR=0
前ページに戻る---> RETURN