6.8 DocumentType节点DocumentType节点是Document节点的一个子节点。我们已经知道,解析器的parse方法将整个被解析的XML文件封装成一个Document节点返回,Document节点的两个子节点的类型分别是DocumentType类型和Element类型,其中的DocumentType节点对应着XML文件所关联的DTD文件,通过进一步获取该节点子孙节点来分析DTD文件中的数据。Document节点调用getDoctype() 返回当前节点的DocumentType子节点。
1.获取DTD的基本信息
假如XML文件中的DOCTYPE声明为:
<!DOCTYPE 房子 PUBLIC "-//ISO88//beijing//ForXML/Ch" "b1.dtd"
那么DocumentType节点调用getName()方法返回的是:
房子
调用getPublicId()方法返回的是:
-//ISO88//beijing//ForXML/Ch
调用getSystemId()方法返回的是:
b1.dtd
一个XML文件可以关联一个外部DTD或一个内部DTD,也可二者皆有(见第3.9节)。如果XML关联一个内部DTD,DocumentType节点调用getInternalSubset()方法可以返回内部DTD的内容。
下面的例子7通过DocumentType节点获取DTD的有关信息。例子7中的“b1.dtd”是“cha6_7.xml”关联的外部DTD文件,“cha6_7”也关联内部的DTD。
例子7(效果如图6.9所示)
 |
| 图6.9 获取DTD的信息和内容(部分) |
b1.dtd <!ELEMENT 房子 ANY > <!ELEMENT 门 (锁,把手) > <!ELEMENT 锁 (#PCDATA) > <!ELEMENT 把手 (#PCDATA)> Cha6_7.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE 房子 PUBLIC "-//ISO88//beijing//ForXML/Ch" "b1.dtd" [ <!ELEMENT 窗 (#PCDATA) > <!ELEMENT 电梯 (#PCDATA) > <!ELEMENT 电灯 (#PCDATA) > ]> <房子> <门> <锁> 老虎牌 </锁> <把手> 熊猫牌 </把手> </门> <窗> 铝合金窗户 </窗> <电梯> 云升牌 </电梯> <电灯> 红星牌 </电灯> </房子> JAXPSeven.java import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.*; public class JAXPSeven { public static void main(String args[]) { try { DocumentBuilderFactory factory= DocumentBuilderFactory. newInstance(); DocumentBuilder builder= factory. newDocumentBuilder(); Document document= builder. parse(new File("Cha6_7.xml")) ; DocumentType doctype=document.getDoctype(); String DTDName=doctype.getName(); System.out.println("DTD名字:"+DTDName); String publicId=doctype.getPublicId(); System.out.println("public标识:"+publicId); String systemId=doctype.getSystemId(); System.out.println("system标识:"+systemId); String internalDTD =doctype.getInternalSubset(); System.out.println("内部DTD:"+internalDTD); } catch(Exception e) { System.out.println(e); } } } |
2.获取实体
我们已经知道,DTD文件中可以定义实体,然后与该DTD文件关联的XML文件可以通过实体引用使用该实体。实体又分为内部实体和外部实体,所谓内部实体就是实体的内容已经包含在DTD文件本身中;而外部实体是指实体的内容是DTD文件以外的其他文件。
解析器将实体封装为Entity节点,DocumentType节点调用
NamedNodeMap getEntities()
方法可以得到全部的实体,该方法返回的NamedNodeMap对象由节点组成,这些节点可以被转换为Entity节点。Entity节点通过调用getTextContent()方法返回实体,如果实体是一个外部文件,Entity节点通过调用getInputEncoding()方法可以返回解析该实体所使用的编码;如果是内部实体,getInputEncoding()方法返回null。
下面的例子8输出DTD定义的全部实体,例子中用的外部实体是ok.txt文件,该文件需使用UTF-8编码保存。
例子8(效果如图6.10所示)
 |
| 图6.10 获取实体 |
Ok.txt 你好,最近工作很忙吧 在忙些什么? a.dtd <!ENTITY 问候 SYSTEM "ok.txt" > <!ENTITY hello "How are you" > <!ENTITY CCTV "中国&<<&中央电视台" > <!ELEMENT root ANY > <!ELEMENT speak ANY > <!ELEMENT hi (#PCDATA)> Cha6_8.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE root SYSTEM "a.dtd"> <root> <speak> &hello;我正在看&CCTV;上的节目。 </speak> <hi> &问候; </hi> </root> JAXPEight.java import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.*; public class JAXPEight { public static void main(String args[]) { try { DocumentBuilderFactory factory= DocumentBuilderFactory. newInstance(); DocumentBuilder builder= factory. newDocumentBuilder(); Document document= builder. parse(new File("cha6_8.xml")) ; DocumentType doctype=document.getDoctype(); NamedNodeMap map=doctype.getEntities(); for(int k=0;k<map.getLength();k++) { Entity node=(Entity)map.item(k); String encoding=node.getInputEncoding(); String content=node.getTextContent(); System.out.println(encoding); System.out.println(content); } } catch(Exception e) { System.out.println(e); } } } |
【责任编辑:
雪花 TEL:(010)68476606-8007】