java中如何对多节点的xml文档进行dom解析
如下XML文档:首先我知道如何解析如hd节点下的code,desc,pid的属性值,但如果是bd下的节点data(因为服务器返回给我的data节点不是每次都有的)而且对于data节点下的嵌套节点usd节点下的属性怎么获取,并且怎么判断是否有data节点,望各位熟悉的指点下,对NodeList,Node和XML的格式做些介绍解释,等我明白了,我会整理一份教程心得,并签上XX指导,谢谢,本人是做J2me的,对XML的解析不是太熟悉,API看的不太明白,我用的是javax.xml.parsers和org.w3c.dom包
<?xml version="1.0" encoding="UTF-8"?> <res> <hd><!--通用请求结果说明信息--> <code>0|1</code><!--请求结果:0、失败,1、成功--> <desc>sucess|其它描述内容</desc> <pid>11</pid><!--协议ID--> </hd> <bd> <data><!--版本数据处理(非必有)--> <usd><!--新域名处理--> <id>0</id><!--序号--> <dn>http://wap.133.cn</dn><!--新域名--> <usd> <udv><!--更新客户端数据版本号--> <id>1</id><!--序号--> <dn>2.0</dn><!--新客户端数据版本号--> <udv> <uud><!--用户ID更新--> <id>2</id><!--序号--> <uid>11001</uid><!--新用户id--> <uud> <uct><!--城市数据更新--> <id>3</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--城市列表--> <it> <n>北京<n/><!--城市中文名--> <p>BEIJING<p/><!--城市拼音编码--> <j>BJ<j/><!--城市简拼编码--> <s>PEK<s/><!--三字码--> </it> ...... </ls> <uct> <utm><!--航班时段更新--> <id>4</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--航班时段列表--> <it> <i>4<i/><!--数据编号--> <n>不限<n/><!--名称--> </it> ...... </ls> <utm> <uac><!--航空公司更新--> <id>5</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--航空公司列表--> <it> <i>CA<i/><!--航空公司简码--> <n>中国国际航空公司<n/><!--航空公司名称--> </it> ...... </ls> <uac> <ucb><!--舱位信息更新--> <id>6</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--舱位列表--> <it> <i>0<i/><!--舱位ID--> <n>经济舱<n/><!--舱位名称--> </it> ...... </ls> <ucb> <ucd><!--证件信息更新--> <id>7</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--证件信息列表--> <it> <i>0<i/><!--证件信息简码--> <n>身份证<n/><!--证件信息名称--> </it> ...... </ls> <ucd> <ucv><!--客户端更新--> <id>8</id><!--序号--> <cvt>版本更新</cvt><!--标题--> <cvc>系统检测到当前有新版本,是否立即更新?</cvc><!--内容--> <url>http://wap.133.cn/Fly.jar</url><!--下载地址--> <ucv> <uoc><!--订票电话更新--> <id>9</id><!--序号--> <to>0|1</to><!--0.替换,1.增加--> <ls><!--订票电话列表--> <it> <i>0<i/><!--订票电话ID--> <tel>4008158888<tel/><!--订票电话--> <n>中航信<n/><!--订票代现名称--> </it> ...... </ls> <uoc> </data> <fly><!--航班信息--> <code>0|1</code><!--查询结果0.失败,1.成功--> <num>47</num><!--航班总数--> <pub>PEK,SHA,2009,05,27</pub><!--公共参数:详情的para1值--> <fm>2,10,1,0,0,0,2,0,0,0,3,0,0,0,4,0,01,01,250,01,01,01,5,0,0,0,6,0,0,0,7,0,1,1,250,1,1,1,0,8,0,0,0,9,0,0,0</fm><!--配色方案--> <!--配色方案说明(对应里面的内容):方案数,要显示的字段数(包括换行控制),要显示的字段号(对应下面标签<it>里面数据的id号),文字大小控制(备用)、颜色方案1,颜色方案2(颜色方案非零用三位表示,比方4后面的01,01,250,为颜色方案1)......除掉这些外,如果遇到数字0便视为换行控制(因为0号ID不可能作为显示字段,被用作返回参数了),实际返回中“,”号将会被空格(\t)取代。--> <ls> <it> <d id="0">CA984,321,0,0720,0930,PEK,PVG,Q,6.7,770,4</d> <!--详细数据:详情的para2值--> <d id="1">国航</d><!--航空公司简称--> <d id="2">CA984</d><!--航班号--> <d id="3">09:30</d><!--起飞时间--> <d id="4">770</d><!--机票价格--> <d id="5">6.7折</d><!--折扣--> <d id="6">北京首都国际机场</d><!--起飞机场名--> <d id="7">上海浦东机场</d><!--到达机场名--> <d id="8">321</d><!--机型--> <d id="9">9</d><!--票数:0~9或9张以上--> <f>1</f><!--选用哪套格式化方案--> </it> ...... </ls> </fly> <bd> </res>
问题补充:
我把XML附件加上来
大家要注意<data>节点下的,这个文件有些没有,因为只有要更新了才会有返回相应节点.望有兴趣的朋友赐教,大家以后一起讨论学习
[code="java"]
import java.io.FileInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class TestXml {
public void parserDATA(org.w3c.dom.Node node){
if (node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
return;
}
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
Element element = (Element) node;
if(element.getTagName().equals("DATA")){
System.out.println(element.TEXT_NODE);
}
org.w3c.dom.NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
parserDATA(list.item(i));
}
}
}
/**
* @param html
* @return 返回w3c dom 对象
*/
public Document getDocument(String html) throws Exception{
//生成html parser
org.cyberneko.html.parsers.DOMParser parser = new org.cyberneko.html.parsers.DOMParser();
//设置网页的默认编码
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://xml.org/sax/features/namespaces", false);
parser.parse(html);
return parser.getDocument();
}
/**
*
*/
public Document getDocument(){
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
FileInputStream in = new FileInputStream("Test1.xml");
Document document = db.parse(in);
return document;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
/**
* 判断是否有data节点
*/
public boolean isData(){
return getDocument().getElementsByTagName("data").getLength()>0?true:false;
}
/**
* 获取一个节点下面某个子节点和子节点属性
*/
public void getChildNodeOrAttr(NodeList list,String NodeName,String NodeAttr){
for(int i=0;i<list.getLength();i++){
Node node = list.item(i);
Element element = (Element)node;
NodeList listChild = list.item(i).getChildNodes();
for(int j=0;j<listChild.getLength();j++){
Node nodeChilde = listChild.item(j);
if (nodeChilde.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
Element elementChilde = (Element)nodeChilde;
if(elementChilde.getTagName().equals(NodeName)){
System.out.println("父节点:"+element.getTagName()+" 已经获取到子节点:"+NodeName+" 子节点属性值:"+elementChilde.getAttribute(NodeAttr));
}
}
}
System.out.println("一个父节点完毕");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestXml testxml = new TestXml();
NodeList nl = testxml.getDocument().getElementsByTagName("it");
testxml.getChildNodeOrAttr(nl,"d","id");
}
}
[/code]
是否完成你的需求了?
可以遍历节点,挨个获取每个节点。
例子如下:
[code="java"]
public void parserNode(org.w3c.dom.Node node){
if (node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
return;
}
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
Element element = (Element) node;
org.w3c.dom.NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
parserNode(list.item(i));
}
}
}
[/code]
我认真看了一下 但是发现很多xml标签不是一对 都只有头而已
如果样板本身就是这种错误语法 那么解析起来就是地狱
如果只是javaeye粘贴xml出现的问题...建议你xml样本以附件的形式上传
本身想帮你一把 可以我惯用dom4j 和你用的包不同 用法也有些不同....