一、XML编程 1.xml编程的两种解析方式 1.1 dom解析 优点:一次加载,多次使用。可以方便的对xml文档进行增删改查 缺点:如果xml文档过大的话,加载的时候会比较占用内存空间比较大,消耗资源,时间长。 1.2 sax解析 优点:一行行读取加载,占用空间少,消耗内存资源少,时间短。 缺点:如果下次使用还得重新加载,只适合查询操作,不适合增删改。 针对加载一次使用一次的问题,可以采取针对性的措施,即在加载的时候可以保存在集合中进行存储。 2.xml解析开发工具包 2.1 jaxp sun公司推出的,集成在j2se中。 2.2 dom4j 3.使用jaxp对xml文档进行dom解析 步骤:1.获取解析器工厂对象 DocumentBuilderFactory newInstance 2.获取解析器 DocumentBuilder new DocumentBuilder 3.解析xml文档,获取Document对象 Document builder.parse(); 4.1 查询节点名称 Element ele = dom.getElementByTagName("xxx").item(index); String name = ele.getTextContent(); syso(name); 4.2 修改节点名称 Element bookEle = (Element) dom.getElementsByTagName("书名").item(0); bookEle.setTextContent("你懂得"); //更新xml TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(new DOMSource(dom), new StreamResult(new FileWriter("book.xml"))); 4.3 添加节点 //添加自定义节点 ,设置标签体 Element price2 = dom.createElement("特价"); price2.setTextContent("99.00元"); //获取父节点 Element parent = (Element) dom.getElementsByTagName("书").item(0); //将自定义节点挂载到父节点 parent.appendChild(price2); //更新xml TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(new DOMSource(dom), new StreamResult(new FileWriter("book.xml"))); 4.4 删除节点 //获取要删除的节点名称 Element price2Ele = (Element) dom.getElementsByTagName("特价").item(0); //获取父节点 Element parent = (Element) price2Ele.getParentNode(); parent.removeChild(price2Ele); //更新xml 4.5 在指定位置增加节点 //创建节点,并设置标签体 Element price2Ele = dom.createElement("特价啦"); price2Ele.setTextContent("100000.99元"); //获取指定位置的节点 Element ele = (Element) dom.getElementsByTagName("售价").item(0); //获取指定位置父节点 Element parent = (Element) ele.getParentNode(); //增加节点 parent.insertBefore(price2Ele, ele); 4.6 获取属性 //获取所需修改属性所在的元素 Element ele = (Element) dom.getElementsByTagName("书").item(1); //获取属性 System.out.println(ele.getAttribute("出版社")); 4.7 修改属性 //获取所需修改属性所在的元素 ` Element ele = (Element) dom.getElementsByTagName("书").item(1); //设置属性 ele.setAttribute("出版社", "大中国出版社"); //更新xml 4.8 添加属性 //获取所需修改属性所在的元素 ` Element ele = (Element) dom.getElementsByTagName("书").item(1); //设置属性 ele.setAttribute("出版社", "大中国出版社"); //更新xml 4.9 删除属性 //获取需要删除的属性所在的元素 Element ele = (Element) dom.getElementsByTagName("书").item(1); //删除属性 ele.removeAttribute("书号"); //更新xml 4.10 遍历所有节点 public static void getAllNodes(Node node) { // 判断如果是node,则打印标签名 if (node.getNodeType() == node.ELEMENT_NODE) { System.out.println(node.getNodeName()); } //判断是否是Element或者Document类型,如果是则判断有没有孩子 if (node.getNodeType() == Node.ELEMENT_NODE || node.getNodeType() == node.DOCUMENT_NODE) { // System.out.println(node.getNodeName()); //如果有孩子进行递归遍历 if (node.hasChildNodes()) { NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { getAllNodes(list.item(i)); } } } //判断如果是标签体,则打印标签体的内容 if (node.getNodeType() == node.TEXT_NODE) { System.out.println(node.getTextContent()); } } 4.使用jaxp对xml文档进行sax解析 sax解析采用事件处理的方式来解析,涉及两个部分解析器和事件处理器。 sax解析器可以使用jaxp的api创建,创建完成后就可以去解析指定的xml文档了。 sax每当读取到xml文档的一部分,都会调用事件处理器的一个方法,事件处理器由程序员定义,以此来决定如何对数据进行操作。 要想获取指定书的属性,应该定义一个计数器,拿到书后再获取属性信息 即使标签没有属性,也会传递一个进来,判断应该使用getLength==0 ,不能使用==null; 步骤://1.获取解析器工厂对象 SAXParserFactory factory = SAXParserFactory.newInstance(); //2.获取解析器 SAXParser parser = factory.newSAXParser(); //3.获取读取器 XMLReader reader = parser.getXMLReader(); //4.注册事件处理器 可以实现ContentHandler接口或者继承DefaultHandler类的方法完成 reader.setContentHandler(new myContentHandler()); //5.解析文档 reader.parse("book.xml"); 案例:将读取到的内容存储到集合中 public class write2List { @Test public void test() throws Exception{ SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); XMLReader reader = parser.getXMLReader(); //注册事件处理器 myContentHandler1 handler = new myContentHandler1(); reader.setContentHandler(handler); //解析文档 reader.parse("book.xml"); List bookList = handler.getBookList(); System.out.println(bookList.size()); } } class myContentHandler1 extends DefaultHandler{ Book book = null; List list = new ArrayList(); String eleName = ""; @Override public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException { if("书".equals(qName)){ book = new Book(); list.add(book); if(attr.getValue("出版社")!=null){ String value = attr.getValue("出版社"); book.setPublish(value); } } if("书名".equals(qName)){ eleName = "书名"; } if("作者".equals(qName)){ eleName = "作者"; } if("售价".equals(qName)){ eleName = "售价"; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if("书名".equals(eleName)){ String name = new String(ch,start,length); book.setBookName(name); } if("作者".equals(eleName)){ String author = new String(ch,start,length); book.setBookName(author); } if("售价".equals(eleName)){ String price = new String(ch,start,length); book.setBookName(price); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { eleName = ""; } public List getBookList(){ return list; } } 5.使用dom4j对xml进行解析 步骤://1.创建解析器 SAXReader reader = new SAXReader(); //2.解析文档 Document dom = reader.read(new File("book.xml")); //3.获取根节点 Element root = (Element) dom.getRootElement(); 5.1 获取第一本书的书名 //4.获取第一本书的书名 Element bookName = root.element("书").element("书名"); // String name = bookName.getName(); String name = bookName.getText(); System.out.println(name); 5.2 增加元素 //4.创建节点 特价 并设置标签体 Element price2Ele = DocumentHelper.createElement("特价"); price2Ele.setText("78.00元"); //5.获取插入标签的 父标签 Element bookEle = root.element("书"); //6.挂载 bookEle.add(price2Ele); //7.更新xml FileWriter fw = new FileWriter("book.xml"); dom.write(fw); fw.close(); 5.3 删除元素 //4.获取其父节点 Element price2Ele = root.element("书").element("特价"); Element parent = price2Ele.getParent(); //5.删除元素 parent.remove(price2Ele); //6.更新xml XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml")); writer.write(dom); 5.4 修改元素 //4.获取索要修改的元素 Element price2Ele = root.element("书").element("特价"); // price2Ele.setName("你好a"); price2Ele.setText("10000.00元"); //5.更新xml OutputFormat format = OutputFormat.createPrettyPrint(); // format.setEncoding("gb2312"); XMLWriter writer = new XMLWriter(new FileWriter("book.xml")); writer.write(dom); writer.close(); 5.5 获取属性 //获取第二本书的属性 List list = root.elements(); //拿到第二本书元素 Element book2Ele = (Element) list.get(1); //获取属性 Attribute attr = book2Ele.attribute("出版社"); //拿到属性值 String value = attr.getText(); System.out.println(value); 5.6 修改属性 将第二本书的属性 修改为 china出版社 //获取属性 Attribute attr = book2Ele.attribute("出版社"); //修改属性 attr.setText("china 出版设"); //更新xml FileWriter fw = new FileWriter("book.xml"); dom.write(fw); fw.close(); 5.7 添加属性 //给第一本书添加出版社属性 //自定义属性,设置内容 Attribute attr = DocumentHelper.createAttribute(book1Ele, "出版社", "我家出版社"); book1Ele.add(attr); //更新XML OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("gb2312"); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),format); writer.write(dom); writer.close(); 5.8 删除属性 // 删除第一本书的出版社属性 Element book1Ele = root.element("书"); // 获取属性 Attribute attr = book1Ele.attribute("出版社"); // 删除属性 book1Ele.remove(attr); // 更新xml FileWriter fw = new FileWriter("book.xml"); dom.write(fw); fw.close(); 二、XML Schema 1.也是定义和描述xml文档结构和内容的模式语言,出现是为了克服DTD的局限性。 2.优势: a.符合xml语法结构 b.内容能被dom sax等api解析 c.对名称空间支持的非常好 d.比DTD支持更多的数据类型,支持用户自定义新的数据类型 e.约束能力非常强大,可以对xml实例文档做出细致的语义限制 f.更加复杂,已经是w3c的标准,正逐步取代DTDs 3.本身是一个xml文件,扩展名为.xsd 一个Schema文档成为模式文档,遵循他写的是实例文档 必须有一个根节点--Schema
时间: 2024-10-10 13:14:16