源生API解析XML文档与dom4j解析XML文档
一、XML语言XML是一种可扩展的标记语言,是一种强类型的语言,类似HTML(超文本标记语言,是一种弱类型的语言)。XML是一种通用的数据交换格式(关系型数据库),综上所诉:XML可以传输数据,也可以存储数据。 1、XML语言书写的注意事项1.XML标签命名自定义【推荐英文】,标签名中不能包含空格 2.XML空格和换行都表示数据,严格区分大小写 3.XML中特殊字符表示的数据需要使用特殊字符编码和HTML一样 4.CDATA区中的数据不会被识别为语法 <![CDATA[王天霸<><><><><><><><><><><><><><><><>]]> 5.xml中存在两个编码,一个是内容编码,另一个是文件编码,文件编码必须要和内容编码一致 二、解析XMl文件方法及示例1、使用源生API解析XMl文档(这种方法也叫做JAXP)代码示例: public?class?XmlTest { @Test public?void?test() throws?ParserConfigurationException,SAXException,IOException { //根据指定xml文件创建一个文件对象 File file = new?File("D:/JAVEEworkspace/xml_study/src/xml_study/contacts.xml"); /* ?* 创建文档创建者工厂对象 , DocumentBuilderFactory是一个抽象类,因此使用里面的 ?* static DocumentBuilderFactory newInstance() ?获取 DocumentBuilderFactory 的新实例。 ?*/ DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance(); /* ?* 获取文档建造者对象,DocumentBuilder也是一个抽象类,因此使用DocumentBuilderFactor抽象类中的 ?* abstract ?DocumentBuilder newDocumentBuilder() 使用当前配置的参数创建一个新的 DocumentBuilder 实例。 ?*/ DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder(); /* ?* 获取Document对象,因为Document是一个接口,因此使用DocumentBuilder抽象类中的 ?* Document parse(File f) 将给定文件的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。 ?*/ Document document = newDocumentBuilder.parse(file); System.out.println("===================================="); //把xml中王天霸的内容读取出来(最原生的,一步步拿取) /* ?* NodeList getElementsByTagName(String tagname) 返回指定标签的元素。 ?* NodeList是一个接口,是对有序节点集合的抽象,里面的方法有: ?* ?int?getLength() 列表中的节点数。 ?* ?Node item(int?index) ??返回集合中的第 index 个项。 ?* Document接口、Element接口的父接口是Node接口,Node接口的String getTextContent() 此属性返回此节点及其后代的文本内容。 ?*/ String textContent = document.getElementsByTagName("name").item(0).getTextContent(); System.out.println(textContent); //获取属性 String textContent2 = document.getElementsByTagName("linkman").item(0).getAttributes().item(0).getTextContent(); System.out.println(textContent2); System.out.println("======================================="); } /* ?* 修改数据 ?*/ @Test public?void?testUpdate() throws?TransformerException,IOException,ParserConfigurationException{ DocumentBuilderFactory newInstance2 = DocumentBuilderFactory.newInstance(); DocumentBuilder newDocumentBuilder2 = newInstance2.newDocumentBuilder(); File file1 = new?File("D:/JAVEEworkspace/xml_study/src/xml_study/contacts.xml"); Document document1 = newDocumentBuilder2.parse(file1); NodeList elementsByTagName = document1.getElementsByTagName("name"); /* ?* ?void setTextContent(String textContent) 设置节点的文本内容 ?*/ elementsByTagName.item(0).setTextContent("赵日天"); /* ?* 现在修改了数据只是修改了内存中的,我们需要将内存中的数据同步到磁盘,因此,我们必须使用Transformer(类,这个类的构造方法受保护), ?* 因此只能使用 TransformerFactory.newTransformer 来获取Transformer实例 ?*/ /* ?* 使用TransformerFactory.newInstance来获取一个TransformerFactory实例, ?* 然后调用newTransformer方法来得到Transformer对象 ?*/ TransformerFactory newInstance = TransformerFactory.newInstance(); Transformer transformer = newInstance.newTransformer(); /* ?* abstract ?void transform(Source xmlSource,Result outputTarget) ? ?* 将xml资源对象 转换到磁盘文件。 ?* Source xmlSource ?因为Source是一个接口,所以使用其子类DOMSource创建一个实例(多态),即: ?* DOMSource(Node n) 创建带有 DOM(文档对象模型) 节点的新输入源实例,而Result也是一个接口, ?* 因此也使用其子类StreamResult来创建一个输出文档实例,即:StreamResult(File f) ?*/ transformer.transform(new?DOMSource(document1),new?StreamResult(file1)); } /* ?* 增加xml数据 ?*/ @Test public?void?testAdd() throws?SAXException,ParserConfigurationException,TransformerFactoryConfigurationError,TransformerException { //创建文档建造者工厂对象 DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance(); //创建一个文档建造者对象 DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder(); File file = new?File("D:/JAVEEworkspace/xml_study/src/xml_study/contacts.xml"); //创建一个文档对象 Document document ?= newDocumentBuilder.parse(file); //获得节点的根root org.w3c.dom.Element root = document.getDocumentElement(); org.w3c.dom.Element createElement = document.createElement("linkman"); org.w3c.dom.Element createElement2 = document.createElement("name"); createElement2.setTextContent("梓沐"); org.w3c.dom.Element createElement3 = document.createElement("email"); createElement3.setTextContent("[email?protected]"); org.w3c.dom.Element createElement4 = document.createElement("address"); createElement4.setTextContent("锦江区"); org.w3c.dom.Element createElement5 = document.createElement("group"); createElement5.setTextContent("10组"); createElement.setAttribute("id","00000"); root.appendChild(createElement); createElement.appendChild(createElement2); createElement.appendChild(createElement3); createElement.appendChild(createElement4); createElement.appendChild(createElement5); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(new?DOMSource(document),new?StreamResult(file)); /* ?* 删除节点 ?* ?Node removeChild(Node oldChild) ?从子节点列表中移除 oldChild 所指示的子节点,并将其返回,必须通过父节点返回。 ?* ?Node getParentNode() ?此节点的父节点。 ?* 我们要删除名叫梓沐的节点 ?*/ } @Test public?void?testDelete() throws?ParserConfigurationException,TransformerException { //创建文档建造者工厂对象 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //创建文档建造者对象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); File file = new?File("D:/JAVEEworkspace/xml_study/src/xml_study/contacts.xml"); //创建解析了指定文件的文档对象 Document document = documentBuilder.parse(file); //获得标签名为name的所有节点 NodeList elements= document.getElementsByTagName("name"); /* ?* for循环去除所有的name节点并得到相应的文本节点,然后与“梓沐”比较, ?* 如果相等则获得这个节点的父节点来删除这个子节点 ?*/ for?(int?i = 0; i < elements.getLength(); i++) { if(elements.item(i).getTextContent().equals("梓沐")){ System.out.println(elements.item(i).getTextContent()); elements.item(i).getParentNode().removeChild(elements.item(i)); } ? } //获得转换器对象 TransformerFactory newInstance = TransformerFactory.newInstance(); Transformer transformer = newInstance.newTransformer(); transformer.transform(new?DOMSource(document),new?StreamResult(file)); ? } } 三、dom4j解析XML文档(都需要导jar包)1、使用源生dom4j解析文档代码示例 public class DOM4JTest { File file = new File("D:/JAVEEworkspace/xml_study/src/xml_dom4j/contacts.xml"); //方法一:使用原生dom4j解析xml文档 @Test public void test() throws DocumentException { /* ?* 使用原生dom4j解析xml文档必须创建dom4j核心对象 ?*/ SAXReader reader = new SAXReader(); //创建一个读取了指定文档的document对象 Document document = reader.read(file); //获取root节点 Element root= document.getRootElement(); /* ?* ?List elements(标签名) 获取下一级的多个标签,返回集合对象 ?* String elementText(标签名) 返回标签中的文本数据 ?* Element element(标签名) 获取下一级的单个标签,返回第一个 ?*/ List elements = root.elements("linkman"); System.out.println(elements); //获取第一个linkman标签 Element element = (Element)elements.get(0); //获取linkman标签下的第一个name标签 Element element2 = element.element("name"); //获取name标签的文本 String text = element2.getText(); System.out.println(text); } 2、使用dom4j中的xpath解析XMl文档XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath 是一门在 XML 文档中查找信息的语言。 代码示例 @Test public void test1() throws DocumentException { //创建dom4j核心对象 SAXReader reader = new SAXReader(); //创建一个读取了指定文档的document对象 Document read = reader.read(file); //通过xpath获取指定的元素(默认是第一个) Node node = read.selectSingleNode("//linkman[2]/name"); String text = node.getText(); System.out.println(text); } /* ?* 修改值 ?*/ @Test public void test2() throws DocumentException,IOException { SAXReader reader = new SAXReader(); Document document = reader.read(file); Node node = document.selectSingleNode("//linkman/name"); node.setText("梓沐"); System.out.println(node.getText()); //将内存里面的数据同步到磁盘(创建一个字节输出流的dom4j的转换流对象) XMLWriter writer = new XMLWriter(new FileOutputStream(file)); writer.write(document); writer.close();//上面创建了一个转换流对象,因此要关闭流 } /* ?* 增加元素(一步一步增加) ?*/ @Test public void test3() throws DocumentException,IOException { SAXReader reader = new SAXReader(); Document read = reader.read(file); //获取根节点 Element root = read.getRootElement(); Element linkman = root.addElement("linkman"); Element id = linkman.addAttribute("id","666"); linkman.addElement("name").setText("你好"); linkman.addElement("email").setText("[email?protected]"); linkman.addElement("address").setText("中国"); linkman.addElement("group").setText("北京"); //创建漂亮格式 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileOutputStream(file),format); writer.write(read); writer.close(); } /* ?* 删除指定元素(还是要用到父类元素来删除子类元素) ?*/ @Test public void test4() throws DocumentException,IOException { SAXReader reader = new SAXReader(); Document document = reader.read(file); Node node = document.selectSingleNode("//linkman[2]/name"); Element parentNode = node.getParent(); boolean remove = parentNode.remove(node); System.out.println(remove); //创建一个输出的漂亮格式 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileOutputStream(file),format); writer.write(document); writer.close(); } 四、XML约束1、XML约束的目的:规范XML中书写的内容,XML约束分为:DTD约束、Schema约束 2、DTD约束 DTD约束文件与XML文件关联 <!DOCTYPE contacts SYSTEM “contacts.dtd”> 注意:DTD约束中若出现错误,不会报错 3、Schema约束Schema约束文件与XML文件关联 <contacts xmlns="http://itsource.cn" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://itsource.cn ?contactsSchema.xsd"> Schema约束本质上来说,是一个XML,Schema约束和DTD约束最大的区别就在于:前者使用XML语法来约束Schema本身的内容,即使写错也会报错,但Schema同样也存在致命的缺点,那就是约束本身语法实在有些复杂。 五、DOM模型DOM(Document Object Model)文档对象模型。直白的讲就是Java程序解析结构化文档的时候,在内存中生成的包含当前结构化文档所有内容的一个对象模型。所以说DOM并不是一门技术,而是一门思想,或者更明确的讲是一门访问结构化文档的一种方式。那么当前我们学过的结构化文档有HTML、XML。DOM模型实际上描述的就是标签之间的层级结构。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |