刚刚学习xml解析,先随意写了个xml文件,然后再根据已经写好的xml文件来定义了dtd文件。
写dtd文件的时候主要要注意一下几点:
空元素要用<!ELEMENT image EMPTY>定义,空元素是指<image id="xxx" />这种,而像<bulletID></bulletID>这种不能算作空元素,只能定义为<!ELEMENT bulletID (#PCDATA)> .表示bulletID的内容为文本.
写好之后,可以正常解析了。
然后我看看xml文件,用<!--back-->写了个注释,居然就不能正常运行了。
相关xml代码为:
<iplane>
<images>
<!-- back -->
<image imageID="back" path="com/iplane/pic/libra.jpg" />
<image imageID="enemy_03"
path="com/iplane/pic/enemy_03.png" />
<image imageID="myPlane" path="com/iplane/pic/myPlane.png" />
<image imageID="bullet_00"
path="com/iplane/pic/planemissible.png" />
<image imageID="bullet_01"
path="com/iplane/pic/bullet_enemy_b.png" />
</images>
</iplane>
相关解析代码如下:
NodeList iplaneNodes =e.getChildNodes();
//parse images
Node imageNodes =e.getFirstChild();
NodeList imageList=imageNodes.getChildNodes();
for(int i=0;i<imageList.getLength();i++)
{
Node imageNode = imageList.item(i); //line 1
Element imageNodeElement = (Element) imageNode ; // line 2
String imageID = imageNodeElement.getAttribute("imageID");
String path = imageNodeElement.getAttribute("path");
images.add(new ImageBean(imageID,path));
}
line 2处始终报错:
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeferredCommentImpl cannot be cast to org.w3c.dom.Element
网上搜索了一下,发现此处的错误就是由于加了那条注释引起的。平时只是写xml文件,认为写了个注释不会有什么影响,其实在解析xml文件的时候,注释也会作为一个Node被读入。line 1得到的Node的Type并不属于element,所以line 2 的强制转换会出错。所以这里需要对注释Node进行一下处理。修改之后的代码如下:
NodeList iplaneNodes =e.getChildNodes();
//parse images
Node imageNodes =e.getFirstChild();
NodeList imageList=imageNodes.getChildNodes();
for(int i=0;i<imageList.getLength();i++)
{
Node imageNode = imageList.item(i);
//如果该节点是注释,则跳过
if(imageNode.getNodeType() ==Node.COMMENT_NODE)
{
continue;
}
//该行代码报错,与元素节点的类型有关
Element imageNodeElement = (Element) imageNode ;
String imageID = imageNodeElement.getAttribute("imageID");
String path = imageNodeElement.getAttribute("path");
images.add(new ImageBean(imageID,path));
}
这里涉及到的知识点是:
org.w3c.dom.Node的类型:
查看Node的原码可以看到
public interface Node {
// NodeType
/**
* The node is an <code>Element</code>.
*/
public static final short ELEMENT_NODE = 1;
/**
* The node is an <code>Attr</code>.
*/
public static final short ATTRIBUTE_NODE = 2;
/**
* The node is a <code>Text</code> node.
*/
public static final short TEXT_NODE = 3;
/**
* The node is a <code>CDATASection</code>.
*/
public static final short CDATA_SECTION_NODE = 4;
/**
* The node is an <code>EntityReference</code>.
*/
public static final short ENTITY_REFERENCE_NODE = 5;
/**
* The node is an <code>Entity</code>.
*/
public static final short ENTITY_NODE = 6;
/**
* The node is a <code>ProcessingInstruction</code>.
*/
public static final short PROCESSING_INSTRUCTION_NODE = 7;
/**
* The node is a <code>Comment</code>.
*/
public static final short COMMENT_NODE = 8;
/**
* The node is a <code>Document</code>.
*/
public static final short DOCUMENT_NODE = 9;
/**
* The node is a <code>DocumentType</code>.
*/
public static final short DOCUMENT_TYPE_NODE = 10;
/**
* The node is a <code>DocumentFragment</code>.
*/
public static final short DOCUMENT_FRAGMENT_NODE = 11;
/**
* The node is a <code>Notation</code>.
*/
public static final short NOTATION_NODE = 12;
...................................................
Node共有12种类型:
节点类型 | 描述 | 子元素 |
---|---|---|
Document | 表示整个文档(DOM 树的根节点) |
|
DocumentFragment | 表示轻量级的 Document 对象,其中容纳了一部分文档。 |
|
DocumentType | 向为文档定义的实体提供接口。 | None |
ProcessingInstruction | 表示处理指令。 | None |
EntityReference | 表示实体引用元素。 |
|
Element | 表示 element(元素)元素 |
|
Attr | 表示属性。 |
|
Text | 表示元素或属性中的文本内容。 | None |
CDATASection | 表示文档中的 CDATA 区段(文本不会被解析器解析) | None |
Comment | 表示注释。 | None |
Entity | 表示实体。 |
|
Notation | 表示在 DTD 中声明的符号。 | None |