欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java day35 xml文件解析

程序员文章站 2024-02-26 21:14:58
...

解析xml数据

直接上代码

import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.Attribute;
import org.dom4j.io.SAXReader;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * dom sax dom4j 解析 student.xml
  *    需要导入JUnit5 dom4j-2.1.3
 *@author 石原里美 
 * */
public class Test1 {
	
	//dom解析
	@org.junit.Test
	public void test1() throws Exception {
		//创建解析器工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		
		//创建dom解析器
		DocumentBuilder builder = factory.newDocumentBuilder();
		
		//获取一个Dcument 对象,指定要解析的文件
		Document document = builder.parse("xml/Student.xml");
		
	
		//调用该方法解析所有节点
		Test1.print(document);
	}
	
	//递归调用该方法遍历获取所有节点
	public static void print(Node node) {
		//判空处理
		if(node == null) {
			throw new RuntimeException("导入节点为空");
		}
		
		//判断node.getNodeType() 的类型,然后执行相应的操作
		switch (node.getNodeType()) {
		//根节点
		case Node.DOCUMENT_NODE :
			//向下转型
			Document document = (Document) node;
			
			//获取根节点
			Element element = document.getDocumentElement();
			
			
			
			//继续调用该方法
			print(element);
			break;
		//元素节点
		case Node.ELEMENT_NODE:
			element = (Element) node;
			
			//打印根节点
			System.out.print("<"+ element.getNodeName());
			//获取所有属性
			NamedNodeMap attributes = element.getAttributes();
			//判断是否有属性
			if(attributes.getLength()>0) {
				for (int i = 0; i < attributes.getLength(); i++) {
					//调用该方法
					print(attributes.item(i));
				}
			}
			System.out.print(">");
			//获取所有子节点
			NodeList childNodes = element.getChildNodes();
			//判断是否有子节点
			if(childNodes.getLength()>0) {
				for (int i = 0; i < childNodes.getLength(); i++) {
					print(childNodes.item(i));
				}
			}
			//打印结束标签
			System.out.print("</"+element.getTagName()+">");
			break;
		//文本节点
		case Node.TEXT_NODE:
			//打印文本
			System.out.print(node.getNodeValue());
			break;
		//属性节点
		case Node.ATTRIBUTE_NODE:
			//转为为属性节点
			Attr attr = (Attr) node;
			//打印属性名字和属性值
			System.out.print(" "+attr.getName()+"=\""+attr.getValue()+"\"");
			break;
			
		//其他节点
		default:
			throw new RuntimeException("意外节点");
		}
	}
	
	//sax解析
	@org.junit.Test
	public void test2() throws Exception {
		//创建sax解析器工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//创建sax对象
		SAXParser saxParser = factory.newSAXParser();
		//解析xml文件,重写DefaultHandler类中的方法,进行事件处理
		saxParser.parse("xml/Student.xml", new DefaultHandler() {
			
			//当解析xml文件开头时候会自动调用该方法,初始方法
			@Override
			public void startDocument() throws SAXException {
				System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			}
			
			/**
			 *  当解析器解析到一个开始标签的时候调用该方法
			 * @param uri命名空间 
			 * @param localName  本地名称(不带前缀)
			 * @param qName 限定名称,标签名称(带前缀)
			 * @param attributes 该节点上的属性列表
			 * */
			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes)
					throws SAXException {
				
				//打印标签名字
				System.out.print("<" + qName);
				//判断是否存在属性
				if(attributes.getLength()>0) {
					for (int i = 0; i < attributes.getLength(); i++) {
						//打印属性名字和对应的字
						System.out.print(" "+ attributes.getQName(i)+"="+attributes.getValue(i));
					}
				}
				System.out.print(">");
			}
			
			//当解析到一个结束标签的时候 调用该方法
			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				System.out.print("</"+qName+">");
			}
			/**
			 * 当解析到文本的时候调用该方法
			 * ch 字符数组
			 * start 起始下标
			 * length 数组长度
			 * */
			@Override
			public void characters(char[] ch, int start, int length) throws SAXException {
				System.out.print(new String(ch,start,length));
			}
			
			//调用该方法解析结束
			@Override
			public void endDocument() throws SAXException {
				
				System.out.println("\n解析结束");
			}
		});
	}

	//dom4j 解析
	@org.junit.Test
	public void test3() throws Exception {
		//获取一个解析器
		SAXReader saxReader = new SAXReader();
		//获取对应文件的Document 因为在同一类中导入了不同包下的Document 所以要指定是那个包下
		org.dom4j.Document read = saxReader.read("xml/Student.xml");
		//获取根节点
		org.dom4j.Element root = read.getRootElement();
		System.out.println(root.getName());
		
		//获取所有的子节点
		List<org.dom4j.Element> list = root.elements();
		//遍历所有节点
		list.forEach(t->{
			//打印节点名字
			System.out.println(t.getName());
			//获取所有属性
			List<Attribute> attributes = t.attributes();
			//遍历所有属性
			attributes.forEach(s->{
				//打印属性的名字和对应的数值
				System.out.println(s.getName()+":"+s.getValue());
				//得到前缀的命名空间,理论上是可以得到,但控制台是得不到的
				System.out.println(s.getNamespacePrefix());
				//得到默认的命名空间
				System.out.println(s.getNamespaceURI());
				
			});
			//继续获取子节点的子节点
			List<org.dom4j.Element> elements = t.elements();
			elements.forEach(l->{
				//获取节点名字
				System.out.println(l.getName());
				//获取文本 去掉首尾空格
				System.out.println(l.getTextTrim());
			});
			
		});
		
		
	}
}

Student.xml

<?xml version="1.0" encoding="UTF-8"?>

<students>
	<x:student id = "x1" xmlns:x="http://www.tt.com/XML/ns/x/">
		<name>石原里美</name>
		<age>18</age>
	</x:student>
	<student id = "x2">
		<name>小十元</name>
		<age>27</age>
	</student>
	<student id = "x3" xmlxmlns = "http://www.tt.com/XML/ns/x/s">
		<name>柠檬</name>
		<age>20</age>
	</student>
</students>

构建一个xml

import java.io.PrintWriter;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
 * @author 石原里美
 * dom4j去构建家族的xml
	<ancestors>
		<father id="1234567890">
			<name>李四</name>
			<salary>1231.11</salary>
		<father>
		<son id="ssss">
			<name>李四1</name>
			<salary>1221.11</salary>
		<son>
	</ancestors>
	*/
public class Test2 {
	public static void main(String[] args) throws Exception {
		//创建一个Document对象
		Document document = DocumentHelper.createDocument();
		//添加一个注解
		document.addComment("家族");
		//添加根节点
		Element element = document.addElement("ancestors");
		//添加父亲节点及其属性
		Element e1 = element.addElement("father").addAttribute("id", "1234567890");
		//添加父亲节点的子节点并赋值
		e1.addElement("name").addText("李四");
		e1.addElement("salary").addText("1231.11");
		//添加儿子节点及其属性
		Element e2 = element.addElement("son").addAttribute("id", "ssss");
		//添加儿子节点的子节点并赋值
		e2.addElement("name").addText("李四1");
		e2.addElement("salary").addText("1221.11");
		//设置格式
		OutputFormat out = new OutputFormat();
		//设置编码值
		out.setEncoding("utf-8");
		//设置缩进
		out.setIndent(true);
		//设置换行
		out.setNewlines(true);
		//将创建好的Document树写出去
		//创建一个Xml对象
		XMLWriter writer = new XMLWriter(new PrintWriter("xml/ancestors.xml"),out);
		writer.write(document);
		writer.flush();
		writer.close();
		
	}
}

练习
将cd.xml封装对象,并且将所有的对象存储起来到一个文件

<?xml version="1.0" encoding="UTF-8"?>
<cds>
	<cd id="x112">
		<name>周杰伦</name>
		<price>155.5</price>
		<title>七里香</title>
	</cd>
	<cd id="x113">
		<name>林俊杰</name>
		<price>156.1</price>
		<title>江南</title>
	</cd>
	<cd id="x114">
		<name>蔡依林</name>
		<price>155.65</price>
		<title></title>
	</cd>
	<cd id="x115">
		<name>蔡徐坤</name>
		<price>15.61</price>
		<title>篮球</title>
	</cd>
	<cd id="x116">
		<name>毛不易</name>
		<price>156.1</price>
		<title>入海</title>
	</cd>
</cds>

答案

封装一个唱片类

import java.io.Serializable;

public class Record implements Serializable {
	private static final long serialVersionUID = 1L;
	private String id;
	private String name;
	private double price;
	private String title;
	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 double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	@Override
	public String toString() {
		return "Record [id=" + id + ", name=" + name + ", price=" + price + ", title=" + title + "]";
	}
	
}

主程序

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Test3 {
	static int i =1;
	public static String id;
	public static String name;
	public static String price;
	public static String title;
	
	//将对象传输到指定文件
	public void encapsulation(Record record) throws Exception {
		ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("record.txt",true));
		outputStream.writeObject(record);
		outputStream.flush();
		outputStream.close();
		
	}

	
	public static void main(String[] args) throws Exception {
		Record record = new Record();
		
		TreeSet<String> set =new TreeSet<>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				// TODO Auto-generated method stub
				return 1;
			}
		});
		SAXReader reader = new SAXReader();
		Document read = reader.read("xml/cd.xml");
		Element element = read.getRootElement();
		new Test3().print(element,set);
		
		set.forEach(t->{
			
			switch (i%4) {
			case 1:
				record.setId(t);
				i++;
				break;
			case 2:
				record.setName(t);
				i++;
				break;
			case 3:
				record.setPrice(Double.parseDouble(t));
				i++;
				break;
			case 0:
				record.setTitle(t);
				i = 1;
				try {
					new Test3().encapsulation(record);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;

			default:
				break;
			}
		});
	}
	
	//获取相同的xml数据
	public  void print(Element element,TreeSet set) {
		List<Element> elements = element.elements();
		if(elements.size()>0) {
			elements.forEach(t->{
				
				switch (t.getName()) {
				case "name":
					name = t.getTextTrim();
					set.add(name);
					break;
				case "price":
					price =t.getTextTrim();
					set.add(price);
					break;
				case "title":
					title = t.getTextTrim();
					set.add(title);
					break;
					
				default:
					break;
				}
				List<Attribute> attributes = t.attributes();
				attributes.forEach(l->{
					if("id".equals(l.getName())) {
						id = l.getValue();
						set.add(id);
					}
				});
				print(t, set);
				
			});
			
		
		}
		
	}
}

相关标签: xml java