[Java]利用DOM解析DOM文件|利用socket发送XML DOM

来源:互联网 发布:淘宝商城男皮鞋正品 编辑:程序博客网 时间:2024/06/15 10:11

DOM的特点是随机读写查询,但是一次性要把xml读到内存里,对于大的xml文件而言,不是个好方法。

加之我个人觉得W3C的Document这套体系的坑比较多,如果要用的话,需要非常系统的学习才能避开这些坑,挺麻烦的。

所以我还是建议采用SAX或其他已包装好的API来写xml比较好。


看了一圈,感觉写得简洁、系统性的博客不多,大多嵌套了太多其他杂乱的相关知识。

但是这篇文章说得很是明白:http://www.cnblogs.com/shenliang123/archive/2012/05/11/2495252.html


>DOM下利用Java对XML进行解析(导包:javax.xml.parsers.*)

//1.获取工厂类DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();//2.从工厂中得到一个解析器DocumentBuilder db=dbf.newDocumentBuilder();//3.利用解析器解析文件,获得document对象Document doc=db.parse(new File(url));

利用parse方法获取Document共有以下几种方法:

关于Document与String互转,可以参考这里:http://kingxss.iteye.com/blog/1026954

利用第一个方法,可以由String构建一个DOM。关于InputSource(包:org.xml.sax.*)的问题,参见文末。

--------------------------

由于我们的目的只是为了获取Document,所以上面的代码可以更加的精简,把1、2步合成到一个地方去,所以整个步骤最后只有两步:

DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();//获取解析器Document doc=db.parse(new File(url));//从文件解析成document文件

接下来,从这个document文件对象中获取每个字节点的列表,并对单个节点的数据进行输出(相当于解析获取数据):

//4.得到所有根部节的列表NodeList list=doc.getElementsByTagName("employee");//或 doc.getChildNodes();//5.遍历、解析输出等操作for(int i=0;i<list.getLength();i++){Node n=list.item(i);//假设这里用的是Node进行操作if(n.getNodeType()==Node.ELEMENT_NODE){//坑1:判断是否为有效文本字符System.out.println("\t"+n.getNodeName()+":"+n.getTextContent());//坑2:getNodeValue()方法输出均为null}}

注意到上面的代码我标注了两个坑,待会儿我再来说。


-----------------------

BTW:

有人可能要问,如果用Element进行操作,是不是就能避开空白文本的问题呢?比如:

for(int j=0;j<nlist.getLength();j++){Element e=(Element)nlist.item(j);        //输出操作等,略}
答案是不能。注意到我们上面是采用:
NodeList list=doc.getElementsByTagName("employee");//语句1

的方法获取节点列表的,也就意味着,空白节点(空格啥的)也进来了。此处进行Node->Element的强制转换很可能报错类型转换失败,处理方法有两种:

1.把语句1中的方法换成:getChildNodes()。

但这样其实十分不灵活,没法按标签获取。

2.添加判断,也就是:

Node info=nlist.item(j);if(info.getNodeType()==Node.ELEMENT_NODE){Element e=(Element) info;}
但这样看着非常多此一举。


>利用socket发送xml文件

xml作为一种数据类型,肯定免不了在不同的服务器间进行传送。

但我个人建议还是采用json来进行这种数据交换(更轻量化、更快捷),或者至少,不要用DOM下的xml进行这种操作。

json的相关内容见此:

http://blog.csdn.net/shenpibaipao/article/details/71760226


但如果你执意要用DOM进行这个操作,好吧,接着往下看:

首先,我们知道socket发送的数据可以是字符串,或者随意什么字节流,那么我们只要把xml编译成一个string或是bytes[]就可以发送了。

关于socket的相关知识看此:

http://blog.csdn.net/shenpibaipao/article/details/70176038

至于转化和再编成document文件,代码见下:

//转化为xml-string便于用socket发送Transformer tr=TransformerFactory.newInstance().newTransformer();//获得一个转化器tr.setOutputProperty("encoding","UTF-8");//设置编码格式ByteArrayOutputStream  bos  =  new  ByteArrayOutputStream();tr.transform(new DOMSource(doc), new StreamResult(bos));//bos就是要发送的流//再编码InputStream is= new ByteArrayInputStream(bos.toString().getBytes());Document doc2=db.parse(is);//doc2就是接收方获取到的数据再编码成document的

这里还有一个坑,是关于InputSource()方法的,称其为坑3,留到下面再说。

至此,具体应用部分讲完了。后续会考虑更新DOM下的xml“改删加”操作,以及SAX的解析。


>神坑

(下面这部分是基础知识的内容,如果只是偏向应用,请直接无视,等遇上问题了再来看)

其一:n.getNodeType()==Node.ELEMENT_NODE 

写这一行的目的是为了判断这个节点是否是有效的标签节点,也就是:<tag>value</tag>。

因为空白字符(空格换行制表符等)并不会被默认丢弃,而是被单做一个有效文本,所以如果不进行这一行的判定,你很可能System.out.plintln(...)出来的字符串会是:#text

-----------

其二:getNodeValue()方法输出均为null

肯定不止我一个人注意到除了getTextContent方法,还有一个名字更为蛊惑的getNodeValue,要是一没注意,铁定就着道了。

为什么getNodeValue输出的都是null呢?

因为Dom解析器中Node和Element是一个内含的关系,Node指的是哪些呢?

答案是任何,一个空格,一个标签,一个Element都可以是一个Node。

而Element指的是<tag>value</tag>这样的东西。(可以认为Element属于Node)

而Node的getNodeValue只有对是Element的Node的内容才有意义。

所以我其实非常无语这个方法的原始设定,感觉除非是什么特殊用途,不然没啥能用得上的地方,还容易造成歧义。

这里可看进一步研究其差异:

http://blog.csdn.net/qq_19457117/article/details/51137415

-----------

其三:DocumentBuilder.parse(InputSource is)方法无效

这个真的是神坑。明明有这个方法,但是无论怎么输入都是不对的:

StringReader sr = new StringReader(bos.toString());   InputSource is=new InputSource(sr);Document doc2=db.parse(is);//此处编译不通过,如下图:



原因是什么呢?其实这是个抽象方法:


且这个InputSource是属于包:org.xml.sax.InputSource,导错包就会导致参数不匹配。





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 1岁宝宝不肯喝水怎么办 三个月宝宝体检说严重缺钙怎么办 1岁半宝宝不吃药怎么办 1岁宝宝抗拒吃药怎么办 六个月宝宝不爱吃辅食怎么办 宝宝九个月了不爱吃辅食怎么办 八个月宝宝不喜欢吃辅食怎么办 小孩米粉吃多了怎么办 宝宝四个月了奶水不足怎么办 4个月奶水不足怎么办 孩子不吃奶粉母乳又不够怎么办 宝宝吃母乳上火了怎么办 5个月宝宝厌奶期怎么办 九个月宝宝不吃奶粉怎么办 第5个月奶不够吃怎么办 九个月的宝宝不吃奶粉怎么办 9个月宝宝不肯吃怎么办 11个月不吃辅食怎么办 4个月母乳不足怎么办 宝宝四个月奶不够怎么办 四个月宝宝奶不够吃怎么办 宝宝吃母乳偏瘦怎么办 宝宝吃母乳很瘦怎么办 8个月宝宝流汗太多怎么办 奶水多乳房胀疼怎么办 乳房胀奶奶水减少怎么办 宝宝五个月奶水不够吃怎么办 梦见鬼在梦里怎么办 宝宝晚上奶水不够吃怎么办 十个月晚上奶水不够吃怎么办 产妇晚上奶水不够吃怎么办 刚出生的宝宝不吃母乳怎么办 宝宝六个月奶不够吃怎么办 六个月奶不够吃怎么办 刚出生奶不够吃怎么办 做梦醒了看见鬼怎么办 宝宝到陌生地方哭闹怎么办 大人生病住院小孩没人带怎么办 孕妇被小猫抓了怎么办 怀孕了家里有猫怎么办 厕所被湿纸巾堵了怎么办