[Java]利用DOM解析DOM文件|利用socket发送XML DOM
2017-05-29 16:00
253 查看
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.*)
利用parse方法获取Document共有以下几种方法:
关于Document与String互转,可以参考这里:http://kingxss.iteye.com/blog/1026954
利用第一个方法,可以由String构建一个DOM。关于InputSource(包:org.xml.sax.*)的问题,参见文末。
--------------------------
由于我们的目的只是为了获取Document,所以上面的代码可以更加的精简,把1、2步合成到一个地方去,所以整个步骤最后只有两步:
接下来,从这个document文件对象中获取每个字节点的列表,并对单个节点的数据进行输出(相当于解析获取数据):
注意到上面的代码我标注了两个坑,待会儿我再来说。
-----------------------
BTW:
有人可能要问,如果用Element进行操作,是不是就能避开空白文本的问题呢?比如:
的方法获取节点列表的,也就意味着,空白节点(空格啥的)也进来了。此处进行Node->Element的强制转换很可能报错类型转换失败,处理方法有两种:
1.把语句1中的方法换成:getChildNodes()。
但这样其实十分不灵活,没法按标签获取。
2.添加判断,也就是:
>利用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文件,代码见下:
这里还有一个坑,是关于InputSource()方法的,称其为坑3,留到下面再说。
至此,具体应用部分讲完了。后续会考虑更新DOM下的xml“改删加”操作,以及SAX的解析。
>神坑
(下面这部分是基础知识的内容,如果只是偏向应用,请直接无视,等遇上问题了再来看)
写这一行的目的是为了判断这个节点是否是有效的标签节点,也就是:<tag>value</tag>。
因为空白字符(空格换行制表符等)并不会被默认丢弃,而是被单做一个有效文本,所以如果不进行这一行的判定,你很可能System.out.plintln(...)出来的字符串会是:#text
-----------
肯定不止我一个人注意到除了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
-----------
这个真的是神坑。明明有这个方法,但是无论怎么输入都是不对的:
原因是什么呢?其实这是个抽象方法:
且这个InputSource是属于包:org.xml.sax.InputSource,导错包就会导致参数不匹配。
加之我个人觉得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,导错包就会导致参数不匹配。
相关文章推荐
- Java利用socket连接到一台主机并向主机发送文件
- java,利用一个socket发送多个文件
- 利用java的Dom解析XML文件
- 利用java Socket发送,接收文件.
- Java利用socket连接到一台主机并向主机发送文件
- 在silverlight中利用socket发送图片或文件
- JAVA语言利用DOM解析XML文件
- Java利用TCP协议发送文件(三)--客户端设计
- Java--Dom解析XML文件
- java 利用socket传输文件
- 利用DOM解析xml文件
- 【java】利用servlet解析报文,上传文件
- 黑马程序员_王康 java利用DOM4J解析XML文件
- java Socket 客户端向服务器端发送流(不是文件),服务器端read出现阻塞问题
- Java 小例子:通过 Socket 发送和接收文件
- Java实现Socket发送和接收文件的代码
- java语言连接mysql数据库并利用XML解析工具DOM生成XML文件,然后利用DOM SAX对所生成XML文件里的详细信息进行解析
- java中DOM解析xml文档却找不到文件
- Java利用TCP协议发送文件(二)--数据包设计
- Java--Dom解析XML文件