Java Web开辟实战典范
在项目开辟中,HTML的重要功用是举行数据展现,而要举行数据存储组织的规范化就须要运用XML。XML有本身的语法,而且一切的标记元素都能够由用户恣意定义。
1、熟悉XML
XML(eXtended Markup Language,可扩大的标记性言语)供应了一套跨平台、跨收集、跨递次的言语的数据形貌体式格局,运用XML能够方便地完成数据交换、系统配置、内容管理等罕见功用。
XML与HTML相似,都属于标记性言语。最大的差别时HTML中的元素都是牢固的,且以显现为主,而XML言语中的标记都是由用户自定义的,重要以数据保留为主。
XML和HTML的比较
现实上一切的XML文件都由前导区和数据区两部份构成。
前导区:划定出XML页面的一些属性,有以下3个属性:
version:示意运用的XML版本,如今是1.0。
encoding:页面中运用的笔墨编码,假如有中文,则一定要指定编码。
standalone:此XML文件是不是是自力运转,假如须要举行显现能够运用CSS或XSL掌握。
属性涌现的递次是牢固的,version、encoding、standalone,一旦递次不对,XML将涌现毛病。
<?xml version="1.0" encoding="GB2312" standalone="no"?>数据区:一切的数据区必需有一个根元素,一个根元素下能够寄存多个子元素,然则请求每个元素必需完毕,每个标记都是辨别大小写的。
XML言语中供应了CDATA标记来标识文件数据,当XML剖析器处置惩罚到CDATA标记时,它不会剖析该段数据中的任何标记或标记,只是将原数据一成不变的传递给运用递次。
CDATA语法花样:
<![CDATA[] 不剖析内容 ]>
2、XML剖析
在XML文件中因为更多的是形貌信息的内容,所以在获得一个XML文档后用该运用递次根据个中元素的定义称号掏出对应的内容,如许的操纵就称为XML剖析。
在XML剖析中W3C定义了SAX和DOM两种剖析体式格局,这两种剖析体式格局的递次操纵以下:
XML剖析操纵
能够看出,运用递次不是直接对XML文档举行操纵的,而是起首由XML剖析器对XML文档举行剖析,然后运用递次经由过程XML剖析器所供应的DOM接口或SAX接口对剖析组织举行操纵,从而间接地完成了对XML文档的接见。
2.1、DOM剖析操纵
在运用递次中,基于DOM (Document Object Model,文档对象模子)的XML剖析器将一个XML文档转换成一个对象模子的鸠合(平常称为DOM树),运用程勋恰是经由过程对这个对象模子的操纵,来完成对XML文档数据的操纵。经由过程DOM接口,运用递次能够在任何时候接见XML文档中的任何一部份数据,因而,这类这类运用DOM接口的机制也被称作随机接见机制。
因为DOM剖析器把悉数XML文档转化成DOM树放在了内存中,因而,当文档比较大或许组织比较庞杂时,对内存的需求就比较高,而且关于组织庞杂的树的遍历也是一项耗时的操纵。
DOM操纵会在内存中将一切的XML文件变成DOM树。
在DOM剖析中有以下4个中心的操纵接口:
Document:此接口代表了悉数XML文档,示意悉数DOM树的根,供应了对文档中的数据举行接见和操纵的进口,经由过程Document节点能够接见XML文件中一切的元素内容。
Document接口的经常使用要领
Node:DOM操纵的中心接口中有很大一部份是从Node接口继续过来的。比方Document、Element、Attri等接口。在DOM树中,每个Node接口代表了DOM树中的一个节点。
Node接口的经常使用要领
NodeList:此接口示意一个节点的鸠合,平常用于示意有递次关联的一组节点。比方,一个节点的子节点,当文档转变时会直接 影响到NodeList鸠合。
NodeList接口的经常使用要领
NameNodeMap:此接口示意一组节点和其唯一称号对应的一一对应关联,重要用于属性节点的示意。
出以上4个中心接口外,假如一个递次须要举行DOM剖析读操纵,则须要按以下步骤举行:
(1)竖立DocumentBuilderFactory:DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(2)竖立DocumentBuilder:DocumentBuilder builder = factory.newDocumentBuilder();
(3)竖立Document:Document doc= builder.parse("要读取的文件途径");
(4)竖立NodeList:NodeList nl = doc.getElementsByTagName("读取节点");
(5)举行XML信息读取。
// xml_demo.xml <?xml version="1.0" encoding="GBK"?> <addresslist> <linkman> <name>小明</name> <email>asaasa@163.com</email> </linkman> <linkman> <name>小张</name> <email>xiaoli@163.com</email> </linkman> </addresslist>
DOM完成XML的读取。
package com.demo; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class XmlDomDemo { public static void main(String[] args) { // (1)竖立DocumentBuilderFactory,以用于获得DocumentBuilder DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // (2)经由过程DocumentBuilderFactory,获得DocumentBuilder DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } // (3)定义Document接口对象,经由过程DocumentBuilder类举行DOM树是转换操纵 Document doc = null; try { // 读取指定途径的XML文件,读取到内存中 doc = builder.parse("xml_demo.xml"); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // (4)查找linkman节点 NodeList nl = doc.getElementsByTagName("linkman"); // (5)输出NodeList中第一个子节点中文本节点的内容 for (int i = 0; i < nl.getLength(); i++) { // 掏出每个元素 Element element = (Element) nl.item(i); System.out.println("姓名:" + element.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()); System.out.println("邮箱:" + element.getElementsByTagName("email").item(0).getFirstChild().getNodeValue()); } } }
DOM完成XML的文件输出。
此时就须要运用DOM操纵中供应的各个接口(如Element接口)并手工设置各个节点的关联,同时在建立Document对象时就必需运用newDocument()要领竖立一个新的DOM树。
假如如今须要将XML文件保留在硬盘上,则须要运用TransformerFactory、Transformer、DOMSource、StreamResult 4个类完成。
TransformerFactory类:获得一个Transformer类的实例对象。
DOMSource类:吸收Document对象。
StreamResult 类:指定要运用的输出流对象(能够向文件输出,也能够向指定的输出流输出)。
Transformer类:经由过程该类完成内容的输出。
StreamResult类的组织要领
package com.demo; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; public class XmlDemoWrite { public static void main(String[] args) { // (1)竖立DocumentBuilderFactory,以用于获得DocumentBuilder DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // (2)经由过程DocumentBuilderFactory,获得DocumentBuilder DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } // (3)定义Document接口对象,经由过程DocumentBuilder类举行DOM树是转换操纵 Document doc = null; // 建立一个新的文档 doc = builder.newDocument(); // (4)竖立各个操纵节点 Element addresslist = doc.createElement("addresslist"); Element linkman = doc.createElement("linkman"); Element name = doc.createElement("name"); Element email = doc.createElement("email"); // (5)设置节点的文本内容,即为每个节点增加文本节点 name.appendChild(doc.createTextNode("小明")); email.appendChild(doc.createTextNode("xiaoming@163.com")); // (6)设置节点关联 linkman.appendChild(name); linkman.appendChild(email); addresslist.appendChild(linkman); doc.appendChild(addresslist); // (7)输出文档到文件中 TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = null; try { t = tf.newTransformer(); } catch (TransformerConfigurationException e) { e.printStackTrace(); } // 设置编码 t.setOutputProperty(OutputKeys.ENCODING, "GBK"); // 输出文档 DOMSource source = new DOMSource(doc); // 指定输出位置 StreamResult result = new StreamResult(new File("xml_wirte.xml")); try { // 输出 t.transform(source, result); System.out.println("yes"); } catch (TransformerException e) { e.printStackTrace(); } } }
生成文档:
//xml_write.xml <?xml version="1.0" encoding="GBK" standalone="no"?> <addresslist> <linkman> <name>小明</name> <email>xiaoming@163.com</email> </linkman> </addresslist>
2.2、SAX剖析操纵
SAX(Simple APIs for XML,操纵XML的简朴接口)与DOM操纵差别的是,SAX采纳的是一种递次的形式举行接见,是一种疾速读取XML数据的体式格局。
当运用SAX 剖析器举行操纵时会触发一系列的事宜。
SAX重要事宜
当扫描到文档(Document)最先与完毕、元素(Element)最先与完毕时都邑挪用相干的处置惩罚要领,并由这些操纵要领做出响应的操纵,直到悉数文档扫描完毕。
假如在开辟中想要运用SAX剖析,则起首应当编写一个SAX剖析器,再直接定义一个类,并使该类继续自DefaultHandler类,同时覆写上述的表中的要领即可。
package com.sax.demo; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XmlSax extends DefaultHandler { @Override public void startDocument() throws SAXException { System.out.println("<?xml version=\"1.0\" encoding=\"GBK\"?>"); } @Override public void endDocument() throws SAXException { System.out.println("\n 文档读取完毕。。。"); } @Override public void startElement(String url, String localName, String name, Attributes attributes) throws SAXException { System.out.print("<"); System.out.print(name); if (attributes != null) { for (int x = 0; x < attributes.getLength(); x++) { System.out.print("" + attributes.getQName(x) + "=\"" + attributes.getValue(x) + "\""); } } System.out.print(">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch, start, length)); } @Override public void endElement(String url, String localName, String name) throws SAXException { System.out.print("</"); System.out.print(name); System.out.print(">"); } }
建荔湾SAX剖析器后,还须要竖立SAXParserFactory和SAXParser对象,以后经由过程SAXPaeser的parse()要领指定要剖析的XML文件和指定的SAX剖析器。
竖立要读取的文件:sax_demo.xml
<?xml version="1.0" encoding="GBK"?> <addresslist> <linkman id="xm"> <name>小明</name> <email>xiaoming@163.com</email> </linkman> <linkman id="xl"> <name>小李</name> <email>xiaoli@163.com</email> </linkman> </addresslist>
运用SAX剖析器
package com.sax.demo; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class SaxTest { public static void main(String[] args) throws Exception { //(1)竖立SAX剖析工场 SAXParserFactory factory = SAXParserFactory.newInstance(); //(2)组织剖析器 SAXParser parser = factory.newSAXParser(); //(3)剖析XML运用handler parser.parse("sax_demo.xml", new XmlSax()); } }
经由过程上面的递次能够发明,运用SAX剖析比运用DOM剖析越发轻易。
DOM剖析与SAX剖析的区分
有二者的特机能够发明二者的区分:
DOM剖析适合于对文件举行修正和随机存取的操纵,然则不适合于大型文件的操纵。
SAX采纳部份读取的体式格局,所以能够处置惩罚大型文件,而且只须要从文件中读取特定内容。SAX剖析能够由用户本身竖立本身的对象模子。
2.3、XML剖析的好帮手:jdom
jdom是运用Java编写的,用于读、写、操纵XML的一套组件。
jdom = dom 修正文件的有点 + SAX读取疾速的长处
jdom的重要操纵类
运用jdom生成XML文件
package com.jdom.demo; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.output.XMLOutputter; public class WriteXml { public static void main(String[] args) { // 定义节点 Element addresslist = new Element("addresslist"); Element linkman = new Element("linkman"); Element name = new Element("name"); Element email = new Element("email"); // 定义属性 Attribute id = new Attribute("id", "xm"); // 声明一个Document对象 Document doc = new Document(addresslist); // 设置元素的内容 name.setText("小明"); email.setText("xiaoming@163.com"); name.setAttribute(id); // 设置子节点 linkman.addContent(name); linkman.addContent(email); // 将linkman到场根子节点 addresslist.addContent(linkman); // 用来输出XML文件 XMLOutputter out = new XMLOutputter(); // 设置输出编码 out.setFormat(out.getFormat().setEncoding("GBK")); // 输出XML文件 try { out.output(doc, new FileOutputStream("jdom_write.xml")); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
// jdom_write.xml <?xml version="1.0" encoding="GBK"?> <addresslist> <linkman> <name id="xm">小明</name> <email>xiaoming@163.com</email> </linkman> </addresslist>
运用jdom读取XML文件
package com.jdom.demo; import java.io.IOException; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class ReadXml { public static void main(String[] args) throws JDOMException, IOException { //竖立SAX剖析 SAXBuilder builder = new SAXBuilder(); //找到Document Document readDoc = builder.build("jdom_write.xml"); //读取根元素 Element stu = readDoc.getRootElement(); //获得悉数linkman子元素 List list = stu.getChildren("linkman"); for (int i = 0; i < list.size(); i++) { Element e = (Element) list.get(i); String name = e.getChildText("name"); String id = e.getChild("name").getAttribute("id").getValue(); String email = e.getChildText("email"); System.out.println("----联系人----"); System.out.println("姓名:" + name + "编号:" + id); System.out.println("Email:" + email); } } }
jdom是一种罕见的操纵组件
在现实的开辟中运用异常普遍。
2.4、剖析东西:dom4j
dom4j也是一组XML操纵组件包,重要用来读写XML文件,因为dom4j机能优秀、功用强大,且具有易用性,所以如今已被普遍地运用开来。如,Hibernate、Spring框架中都运用了dom4j举行XML的剖析操纵。
开辟时须要引入的jar包:dom4j-1.6.1.jar、lib/jaxen-1.1-beta-6.jar
dom4j中的所用操纵接口都在org.dom4j包中定义。其他包根据须要把挑选运用。
dom4j的重要接口
用dom4j生成XML文件:
package com.dom4j.demo; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; public class Dom4jWrite { public static void main(String[] args) { // 建立文档 Document doc = DocumentHelper.createDocument(); // 定义个节点 Element addresslist = doc.addElement("addresslist"); Element linkman = addresslist.addElement("linkman"); Element name = linkman.addElement("name"); Element email = linkman.addElement("email"); // 设置节点内容 name.setText("小明"); email.setText("xiaoming@163.com"); // 设置输出花样 OutputFormat format = OutputFormat.createPrettyPrint(); // 指定输出编码 format.setEncoding("GBK"); try { XMLWriter writer = new XMLWriter(new FileOutputStream(new File( "dom4j_demo.xml")), format); writer.write(doc); writer.close(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
// dom4j_demo.xml <?xml version="1.0" encoding="GBK"?> <addresslist> <linkman> <name>小明</name> <email>xiaoming@163.com</email> </linkman> </addresslist>
用dom4j读取XML文件:
package com.dom4j.demo; import java.io.File; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jRead { public static void main(String[] args) { //读取文件 File file = new File("dom4j_demo.xml"); //竖立SAX剖析读取 SAXReader reader = new SAXReader(); Document doc = null; try { //读取文档 doc = reader.read(file); } catch (DocumentException e) { e.printStackTrace(); } //获得根元素 Element root = doc.getRootElement(); //获得悉数的子节点 Iterator iter = root.elementIterator(); while (iter.hasNext()) { //获得每个linkman Element linkman = (Element) iter.next(); System.out.println("姓名:"+linkman.elementText("name")); System.out.println("邮件地址:"+linkman.elementText("email")); } } }
小结
XML重要用于数据交换,而HTML则用于显现。
Java直接供应的XML剖析体式格局分为两种,即DOM和SAX。这两种剖析的区分以下:
DOM剖析是将一切内容读取到内存中,并构成内存树,假如文件量较大则没法运用,然则DOM剖析能够举行文件的修正
SAX剖析是采纳递次的体式格局读取XML文件中,不受文件大小限定,然则不允许修正。
XML剖析能够运用jdom和dom4j第三方东西包,以提拔开辟效力。
以上就是XML剖析基本的细致内容,更多请关注ki4网别的相干文章!