writer.close();
XMLWriter 构造方法: XMLWriter() XMLWriter(OutputFormat format) XMLWriter(OutputStream out) XMLWriter(OutputStream out, OutputFormat format) XMLWriter(Writer writer) XMLWriter(Writer writer, OutputFormat format) 使用: OutputFormat 输出的格式XMLWriter(OutputStream out, OutputFormat format)
static OutputFormat createCompactFormat() 创建默认紧凑格式的静态助手方法。去除空格换行.项目上线的时候 static OutputFormat createPrettyPrint() 创建默认的漂亮打印格式的静态助手方法。有空格和换行.开发调试的时候 OutputFormat format = OutputFormat.createCompactFormat(); 1.创建写出对象XMLWriter writer = new XMLWriter(out,format);
void setEncoding(String encoding) 设置指定编码格式. format.setEncoding("utf-8"); 同时影响了xml文档保存时的编码 和 xml文档声明的encoding的编码(xml解析时的编码) 结论: 使用该方法生成的xml文档避免中文乱码问题。 将一个xml写入到另一个xml文件里面 public void test1()throws Exception{ Document doc = new SAXReader().read(new File("./src/oncs.xml")); Element contactElem = (Element) doc.getRootElement(). elements().get(1); //2.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //2.3 删除属性 idAttr.detach(); FileOutputStream out = new FileOutputStream("d:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); }Attribute.detach(); 删除属性
创建一个xml文档,里面写入内容,再进行一些其他的操作
public class D4j1 { @Test public void Test1() throws Exception{ Document doc = DocumentHelper.createDocument(); //添加属性标签 Element rootElement = doc.addElement("Students"); Element conElement1 = rootElement.addElement("Student"); conElement1.addElement("name"); conElement1.addElement("gender"); conElement1.addElement("grade"); conElement1.addElement("address"); Element conElement2 = rootElement.addElement("Student"); conElement2.addElement("name"); conElement2.addElement("gender"); conElement2.addElement("grade"); conElement2.addElement("address"); //添加属性 conElement1.addAttribute("id", "1"); conElement2.addAttribute("id", "2"); //添加文本 conElement1.element("name").setText("张三"); conElement1.element("gender").setText("男"); conElement1.element("grade").setText("计算机1班"); conElement1.element("address").setText("广州天河"); conElement2.element("name").setText("李四"); conElement2.element("gender").setText("女"); conElement2.element("grade").setText("计算机2班"); conElement2.element("address").setText("广州越秀"); FileOutputStream out = new FileOutputStream("D:/contacts.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } //2.修改id为2的学生的姓名,改为“王丽” @Test public void Test2()throws Exception{ Document doc = new SAXReader().read(new File("D:/contacts.xml")); Iterator<Element> it = doc.getRootElement().elementIterator("Student"); while(it.hasNext()){ Element stuElement = it.next(); //if(stuElement.attributeValue("id").equals("2")){ if(stuElement.attribute("id").getValue().equals("2")){ stuElement.element("name").setText("王丽"); break; } } FileOutputStream out = new FileOutputStream("D:/contacts.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } //3.删除id为2的学生 @Test public void Test3()throws Exception{ Document doc = new SAXReader().read(new File("D:/contacts.xml")); Iterator<Element> it = doc.getRootElement().elementIterator("Student"); while(it.hasNext()){ Element stuElement = it.next(); if(stuElement.attribute("id").getValue().equals("2")){ stuElement.element("name").detach(); break; } } FileOutputStream out = new FileOutputStream("D:/contacts.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } }写出的格式: <Students> <Student id="1"> <name>张三</name> <gender>男</gender> <grade>计算机1班</grade> <address>广州天河</address> </Student> <Student id="2"> <name>李四</name> <gender>女</gender> <grade>计算机2班</grade> <address>广州越秀</address> </Student> </Students>在dom4j中如何使用xPath技术:
1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar(上一个包是核心包,上一个包也要使用) 2)使用xpath方法 List<Node> selectNodes("xpath表达式"); 查询多个节点对象 Node selectSingleNode("xpath表达式"); 查询一个节点对象
删除id值为2的学生标签 //1.查询id为2的学生标签 //使用xpath技术 Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']"); //2.删除标签 stuElem.detach() xPath语法 / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) // 相对路径 表示不分任何层次结构的选择元素。 * 通配符 表示匹配所有元素 [] 条件 表示选择什么条件下的元素 @ 属性 表示选择属性节点 and 关系 表示条件的与关系(等价于&&) text() 文本 表示选择文本内容
xPath语法使用:
public class Demo2 { public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("./src/contact.xml")); String xpath = ""; /** * 1. / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) */ xpath = "/contactList"; xpath = "/contactList/contact"; /** * 2. // 相对路径 表示不分任何层次结构的选择元素。 */ xpath = "//contact/name"; xpath = "//name"; /** * 3. * 通配符 表示匹配所有元素 */ xpath = "/contactList/*"; //根标签contactList下的所有子标签 xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构) /** * 4. [] 条件 表示选择什么条件下的元素 */ //带有id属性的contact标签 xpath = "//contact[@id]"; //第二个的contact标签 //doc.getRootElement().elements().get(1); xpath = "//contact[2]"; //选择最后一个contact标签 xpath = "//contact[last()]"; /** * 5. @ 属性 表示选择属性节点 */ xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象 xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点 xpath = "//contact[@id='002']";//选择id属性值为002的contact标签 (里面的分号不要也行,但是最好加上) xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签 /** *6. text() 表示选择文本内容 */ //选择name标签下的文本内容,返回Text对象 xpath = "//name/text()"; //选择所有name下面的文本 xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签 List<Node> list = doc.selectNodes(xpath); for (Node node : list) { System.out.println(node); } } } 使用xml模拟用户登录效果: public class Demo3 { public static void main(String[] args)throws Exception{ //1.获取用户输入的用户名和密码 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//将字节流转换成字符流 System.out.println("请输入用户名:"); String name = br.readLine(); System.out.println("请输入密码:"); String password = br.readLine(); //2.到“数据库”中查询是否有对应的用户 //对应的用户: 在user.xml文件中找到一个 //name属性值为‘用户输入’,且password属性值为‘用户输入’的user标签 Document doc = new SAXReader().read(new File("./src/user.xml")); Element userElem = (Element)doc.selectSingleNode("//user[@name='" +name +"' and @password='"+password+"']"); if(userElem!=null){ //登录成功 System.out.println("登录成功"); }else{ //登录失败 System.out.println("登录失败"); } } } 使用xpath技术读取一个规范的html文档: public class Demo4 { public static void main(String[] args) throws Exception{ Document doc = new SAXReader().read(new File("./src/personList.html")); //System.out.println(doc); //读取title标签 Element titleElem = (Element)doc.selectSingleNode("//title"); String title = titleElem.getText(); System.out.println(title); /** * 读取联系人的所有信息 * 按照以下格式输出: * 编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx * 编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx * ...... */ //1.读取出所有tbody中的tr标签 List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr"); //2.遍历 for (Element elem : list) { //编号 //String id = ((Element)elem.elements().get(0)).getText(); String id = elem.selectSingleNode("td[1]").getText(); //姓名 String name = ((Element)elem.elements().get(1)).getText(); //性别 String gender = ((Element)elem.elements().get(2)).getText(); //年龄 String age = ((Element)elem.elements().get(3)).getText(); //地址 String address = ((Element)elem.elements().get(4)).getText(); //电话 String phone = ((Element)elem.elements().get(5)).getText(); System.out.println("编号:"+id+"\t姓名:"+name+"\t性别:"+ gender+"\t年龄:"+ age+"\t地址:"+address+ "\t电话:"+phone); } } }DefaultHandler类 :SAX2 事件处理程序的默认基类。
protected SAXParser() 将阻止实例化的受保护构造方法。当看到构造方法不能new 要使用静态方法获得实例 使用: SAXParserFactory.newSAXParser()。 public abstract SAXParser newSAXParser() throws ParserConfigurationException, SAXException使用当前配置的工厂参数创建 SAXParser 的一个新实例。 返回SAXParser newSAXParser()属于SAXParserFactory类的一个方法 静态的使用对象调用,,非静态的使用类的对象调用 protected SAXParserFactory() 受保护构造方法,以强制使用 newInstance()。 static SAXParserFactory newInstance() 获取 SAXParserFactory 的一个新实例。 所以用:SAXParserFactory.newInstance().newSAXParser();读取一个SAX文件:
public class Demo1 { public static void main(String[] args) throws Exception{ //1.创建SAXParser对象 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //使用工厂创建对象 //2.调用parse方法 /** * 参数一: xml文档 * 参数二: DefaultHandler的子类 */ parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); } public class MyDefaultHandler extends DefaultHandler { /** * 开始文档时调用 */ @Override public void startDocument() throws SAXException { System.out.println("MyDefaultHandler.startDocument()"); } /** * 开始标签时调用 * @param qName: 表示开始标签的标签名 * @param attributes: 表示开始标签内包含的属性列表 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("MyDefaultHandler.startElement()-->"+qName); } /** * 结束标签时调用 * @param qName: 结束标签的标签名称 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("MyDefaultHandler.endElement()-->"+qName); } /** * 读到文本内容的时调用 * @param ch: 表示当前读完的所有文本内容 xml的所有内容 * @param start: 表示当前文本内容的开始位置 * @param length: 表示当前文本内容的长度 * char[]( 张三 20) 100 * 98 2 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //得到当前文本内容 String content = new String(ch,start,length); System.out.println("MyDefaultHandler.characters()-->"+content); } /** * 结束文档时调用 */ @Override public void endDocument() throws SAXException { System.out.println("MyDefaultHandler.endDocument()"); } }使用的方法:
void startDocument() : 在读到文档开始时调用 void endDocument() :在读到文档结束时调用 void startElement(String uri, String localName, String qName, Attributes attributes) :读到开始标签时调用 void endElement(String uri, String localName, String qName) :读到结束标签时调用 void characters(char[] ch, int start, int length) : 读到文本内容时调用DOM解析
SAX解析
原理: 一次性加载xml文档,不适合大容量的文件读取
原理: 加载一点,读取一点,处理一点。适合大容量文件的读取
DOM解析可以任意进行增删改成
SAX解析只能读取
DOM解析任意读取任何位置的数据,甚至往回读
SAX解析只能从上往下,按顺序读取,不能往回读
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。
SAX解析基于事件的编程方法。java开发编码相对复杂。
使用SAX读取一个完整的xml文件 package gz.itcast.c_sax; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * 读取contact.xml文件,完整输出文档内容 */ public class Demo2 { public static void main(String[] args)throws Exception { //1.创建SAXParser SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.读取xml文件 MyDefaultHandler2 handler = new MyDefaultHandler2(); parser.parse(new File("./src/contact.xml"), handler); String content = handler.getContent(); System.out.println(content); } } package gz.itcast.c_sax; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SAX处理器程序 * @author APPle */ public class MyDefaultHandler2 extends DefaultHandler { //存储xml文档信息 private StringBuffer sb = new StringBuffer(); //获取xml信息 public String getContent(){ return sb.toString(); } /** * 开始标签 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { sb.append("<"+qName); //判断是否有属性 if(attributes!=null){ for(int i=0;i<attributes.getLength();i++){ //得到属性名称 String attrName = attributes.getQName(i); //得到属性值 String attrValue = attributes.getValue(i); sb.append(" "+attrName+"=\""+attrValue+"\""); } } sb.append(">"); } /** * 文本内容 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //得到当前读取的文本 String content = new String(ch,start,length); sb.append(content); } /** * 结束标签 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { sb.append("</"+qName+">"); } }使用SAX将xml文件写入到list里面: import java.io.File; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * 使用sax解析把 xml文档封装成对象 * @author APPle * */ public class Demo3 { public static void main(String[] args)throws Exception { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyDefaultHandler3 handler = new MyDefaultHandler3(); parser.parse(new File("./src/contact.xml"), handler); List<Contact> list = handler.getList(); for (Contact contact : list) { System.out.println(contact); } } } import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SAX处理程序 * @author APPle */ public class MyDefaultHandler3 extends DefaultHandler { //存储所有联系人对象 private List<Contact> list = new ArrayList<Contact>(); public List<Contact> getList(){ return list; } //保存一个联系人信息 private Contact contact; /** * 思路: * 1)创建Contact对象 * 2)把每个contact标签内容存入到Contact对象 * 3)把Contact对象放入List中 */ //用于临时存储当前读到的标签名 private String curTag; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { curTag = qName; //读取到contact的开始标签创建Contact对象 if("contact".equals(qName)){ contact = new Contact(); //设置id值 contact.setId(attributes.getValue("id")); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { //当前文本内容 String content = new String(ch,start,length); if("name".equals(curTag)){ contact.setName(content); } if("age".equals(curTag)){ contact.setAge(content); } if("phone".equals(curTag)){ contact.setPhone(content); } if("email".equals(curTag)){ contact.setEmail(content); } if("qq".equals(curTag)){ contact.setQq(content); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //设置空时为了避免空格换行设置到对象的属性中 curTag = null; //读到contact的结束标签放入List中 if("contact".equals(qName)){ list.add(contact); } } }<?xml version="1.0" encoding="utf-8"?> <contactList> <contact id="001" name="sdsd"> <name>庄三</name> <age>20</age> <phone>1534151</phone> <email>23234sdfsa@sj555</email> <QQ>646415654</QQ> </contact> <contact id="002"> <name>李四</name> <age>23</age> <phone>232424</phone> <email>2324@af.com</email> <QQ>452156320</QQ> </contact> </contactList> public class Contact { private String id; private String name; private String age; private String phone; private String email; private String qq; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } @Override public String toString() { return "Contact [age=" + age + ", email=" + email + ", id=" + id + ", name=" + name + ", phone=" + phone + ", qq=" + qq + "]"; } }XML:
<?xml version="1.0" encoding="utf-8"?> <contactList> <contact id="001" name="sdsd"> <name>庄三</name> <age>20</age> <phone>1534151</phone> <email>23234sdfsa@sj555</email> <QQ>646415654</QQ> </contact> <contact id="002"> <name>李四</name> <age>23</age> <phone>232424</phone> <email>2324@af.com</email> <QQ>452156320</QQ> </contact> </contactList> 腾不出时间思考的人,迟早会腾出时间来后悔;腾不出时间学习的人,迟早会腾出时间来伤悲。