XML:软件的配置文件,数据的载体(小型的“数据库”)
2)xml标签名称区分大小写
4)xml标签名中间不能使用空格
5)xml标签名不能以数字开头
6)注意: 在一个xml文档中,只有一个根标签
7)属性值必须以引号包含,不能单双引号
8)cdata块 :可以让一些需要进行包含特殊字符的内容统一进行原样输出
//tomcat temp临时目录 work是tomcat 的运行目录,jsp运行产生的临时文件放在这里
XML解析方式:
1、DOM解析 Dom4J
2、SAX解析
DOM解析:
xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容
1、读取 contactInfo.xml 的内容
<?xml version="1.0" encoding="utf-8"?> <!-- encoding 与 文件保存的编码格式一样 --> <contactList> <contact flg="true" id="001" > <name>Mr.L</name> <age>21</age> <phone> 啊啊啊 <length>11</length> <number>13900</number> </phone> </contact> <contact id="002"> <name>小明</name> <age>22</age> <phone>138000</phone> </contact> <![CDATA[ 这里的内容原样输出 , <p>不会被当作xml标签进行解析</p> ]]> </contactList>
public class demo { public static void main(String[] args) { try { SAXReader reader=new SAXReader();//dom4j 创建xml解析器 Document doc=reader.read(new File("./src/contactInfo.xml"));// ./ 项目名称 //eclipse 中 选中上面两行,右键 surround with tryCatch block //System.out.println(doc); //.element("name") 获取子标签中 第一个名称为name的节点 //.nodeIterator(): 得到当前节点下的所有子节点对象(不包含孙以下的节点) Iterator<Node> iter=doc.getRootElement().element("contact").nodeIterator(); while(iter.hasNext()){ System.out.println(iter.next().getName()); //属性id="001" 和 文本 小明 也是 节点,但不是 标签节点 ,无法调用getName(),返回null } } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(e);//出现异常 停止运行 } } @Test public void test() throws Exception{ SAXReader reader=new SAXReader();//dom4j 创建xml解析器 Document doc=reader.read(new File("./src/contactInfo.xml"));// ./ 项目名称 //getChildNodes(doc.getRootElement());//标签 StringBuffer sb=new StringBuffer(); getChildNodes(doc.getRootElement(),sb); System.out.println(sb.toString()); /* 文本 * Element contactOne=doc.getRootElement().element("contact"); * Element contactOne=doc.getRootElement().element("contact"); System.out.println(contactOne.element("name").getText()); System.out.println(contactOne.elementText("phone").trim());//空格和换行也是xml的内容 */ /* 属性 Element contactOne=doc.getRootElement().element("contact"); Attribute attr=contactOne.attribute("id"); System.out.println(attr.getName()+" "+attr.getValue()); System.out.println(contactOne.attributeValue("id")); List<Attribute> list=contactOne.attributes(); for(Attribute attr:list){ System.out.println(attr.getName()+" "+attr.getValue()); } Iterator<Attribute> iter=contactOne.attributeIterator(); while(iter.hasNext()) { Attribute attr=iter.next(); System.out.println(attr.getName()+" "+attr.getValue()); } */ } //获取 标签下的所有 标签 private void getChildNodes(Element element){ System.out.println(element.getName()); /* Iterator<Node> iter=element.nodeIterator(); while(iter.hasNext()){ Node node=iter.next(); if(node instanceof Element){ getChildNodes((Element)node); } }*/ List<Element> list=element.elements();//获取所有子标签 for(Element elt:list){ getChildNodes(elt); } } private void getChildNodes(Element elm,StringBuffer sb){ sb.append("<"+elm.getName()); List<Attribute> list=elm.attributes(); if(list!=null){ for(Attribute attr:list){ sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\""); } } sb.append(">"); Iterator<Node> iter=elm.nodeIterator(); while(iter.hasNext()){ Node node=iter.next(); if(node instanceof Element){ getChildNodes((Element)node,sb); } if(node instanceof Text){ sb.append(((Text)node).getText()); } } sb.append("</"+elm.getName()+">"); } /* * 实用 的方法 */ public void xmlToClass() throws Exception{ List<Contact> list=new ArrayList<Contact>(); SAXReader reader=new SAXReader(); Document doc=reader.read(new File("./src/contactInfo.xml")); Iterator<Element> iter=doc.getRootElement().elementIterator("contact"); //element.elementIterator("标签名");// 指定名称的所有子标签 while(iter.hasNext()){ Element elm=iter.next(); Contact contact=new Contact(); contact.setId(elm.attributeValue("id")); contact.setName(elm.elementText("name")); list.add(contact); } for(Contact contact:list){ System.out.println(contact); } } }
2、修改或生成xml
/** * 1.生成指定内容的xml文档 * @throws Exception */ @Test public void test1() throws Exception{ //1.内存创建xml文档 Document doc = DocumentHelper.createDocument(); //2.写入内容 Element rootElem = doc.addElement("Students"); //2.1 增加标签 Element studentElem1 = rootElem.addElement("Student"); //2.2 增加属性 或 修改属性(同名覆盖) studentElem1.addAttribute("id", "1"); //2.3 增加标签,同时设置文本 studentElem1.addElement("name").setText("张三"); studentElem1.addElement("gender").setText("男"); studentElem1.addElement("grade").setText("计算机1班"); studentElem1.addElement("address").setText("广州天河"); //2.1 增加标签 Element studentElem2 = rootElem.addElement("Student"); //2.2 增加属性 studentElem2.addAttribute("id", "2"); //2.3 增加标签,同时设置文本 studentElem2.addElement("name").setText("李四"); studentElem2.addElement("gender").setText("女"); studentElem2.addElement("grade").setText("计算机2班"); studentElem2.addElement("address").setText("广州越秀"); //node.detach(); 删除 //3.内容写出到xml文件 //3.1 输出位置 FileOutputStream out = new FileOutputStream("e:/student.xml"); //3.2 指定格式 OutputFormat format = OutputFormat.createPrettyPrint(); //OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式.去除空格换行.项目上线的时候 // 设置编码 format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); //3.3 写出内容 writer.write(doc); //3.4关闭资源 writer.close(); }
3、XPath 是在 XML 文档中通过元素和属性进行查找信息的语言, 当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦
jaxen-1.1-beta-6.jar
List<Node> selectNodes(String xpathExpression)
Node selectSingleNode(String xpathExpression) //返回一个Node对象或多个中的第一个对象
语法: 选取节点 使用限定语 使用通配符
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");//1.查询id为2的学生标签
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标签
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()";
xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
List<Node> list = doc.selectNodes(xpath);
for (Node node : list) {
System.out.println(node);
}
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("登录失败");
}
DOM解析 |
SAX解析(跳过) |
原理: 一次性加载xml文档,不适合大容量的文件读取 |
原理: 加载一点,读取一点,处理一点。适合大容量文件的读取 |
DOM解析可以任意进行增删改成 |
SAX解析只能读取 |
DOM解析任意读取任何位置的数据,甚至往回读 |
SAX解析只能从上往下,按顺序读取,不能往回读 |
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 |
SAX解析基于事件的编程方法。java开发编码相对复杂。 |