java解析xml
参考资料
水平有限,欢迎交流
千问ai
阿伟的反射知识学习
泛型知识学习
软件设计模式(java 版)程细柱
目标 xml
<?xml version="1.0" encoding="UTF-8" ?>
<conf>
<farm>SGFarm</farm>
<student>
<name>李四</name>
<age>23</age>
<sex>男</sex>
<address>北京</address>
</student>
<teacher>
<id>0001</id>
<teacherName>王老师</teacherName>
<subject>数学</subject>
<salary>5000</salary>
</teacher>
<grades>
<grade>
<id>001</id>
<studentName>李四</studentName>
<subject>数学</subject>
<score>90</score>
</grade>
<grade>
<id>002</id>
<studentName>王五</studentName>
<subject>数学</subject>
<score>80</score>
</grade>
</grades>
</conf>
解析简单字符串方法
/**
* 从XML文件中读取单一标签的内容,并返回字符串。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @return 返回标签内的文本内容。
*/
public static String readStringTag(String xmlPath, String tagName) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找指定的标签
NodeList nodeList = document.getElementsByTagName(tagName);
if (nodeList.getLength() == 0) {
throw new IllegalArgumentException("No '" + tagName + "' element found in XML file.");
}
// 获取第一个匹配的节点
Node node = nodeList.item(0);
// 检查节点类型是否为元素节点
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
if (element.hasChildNodes()) {
Node childNode = element.getFirstChild();
if (childNode != null && childNode.getNodeType() == Node.TEXT_NODE) {
return childNode.getNodeValue();
}
}
}
throw new IllegalArgumentException("The '" + tagName + "' tag does not contain any text.");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and retrieve string content", e);
}
}
public static void main(String[] args) {
String xmlPath = "src/code/readXml/test.xml";
String tagName1 = "student";
String tagName2 = "teacher";
String tagName3 = "grade";
String tagName4 = "farm";
System.out.println("解析字符串----------------------------------------");
String farmContent = ReadXML.readStringTag(xmlPath, tagName4);
System.out.println("Farm content: " + farmContent);
}
解析对象
解析单一对象
对象学生定义类
class Student {
private String name;
private int age;
private String sex;
private String address;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
对象老师定义类
class Teacher {
private int id;
private String name;
private String subject;
private double salary;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", id=" + id +
", subject='" + subject + '\'' +
", salary='" + salary + '\'' +
'}';
}
}
解析方法
/**
* 从XML文件中读取对象信息,并返回指定类型的对象实例。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @param clazz 目标类型的Class对象,用于类型安全的返回。
* @param mapping 属性名到XML标签的映射。
* @param <T> 泛型类型。
* @return 返回创建的对象实例。
*/
public static <T> T readObjXml(String xmlPath, String tagName, Class<T> clazz, Map<String, String> mapping) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找指定标签名的节点列表
NodeList nodeList = document.getElementsByTagName(tagName);
if (nodeList.getLength() == 0) {
throw new IllegalArgumentException("No '" + tagName + "' element found in XML file.");
}
// 获取第一个匹配节点
Element element = (Element) nodeList.item(0);
// 使用反射创建对象实例
T instance = clazz.getDeclaredConstructor().newInstance();
// 设置对象属性
for (Map.Entry<String, String> entry : mapping.entrySet()) {
String propertyName = entry.getKey();
String xmlTagName = entry.getValue();
Node node = element.getElementsByTagName(xmlTagName).item(0);
if (node != null && node.getFirstChild() != null) {
String value = node.getFirstChild().getNodeValue();
// 设置属性值
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true); // 允许访问私有字段
if (field.getType() == Integer.class || field.getType() == int.class) {
field.setInt(instance, Integer.parseInt(value));
} else if (field.getType() == Long.class || field.getType() == long.class) {
field.setLong(instance, Long.parseLong(value));
} else if (field.getType() == Double.class || field.getType() == double.class) {
field.setDouble(instance, Double.parseDouble(value));
} else if (field.getType() == String.class) {
field.set(instance, value);
}
else {
throw new IllegalArgumentException("Unsupported type for property: " + propertyName);
}
}
}
return instance;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and create object", e);
}
}
public static void main(String[] args) {
String xmlPath = "src/code/readXml/test.xml";
String tagName1 = "student";
String tagName2 = "teacher";
String tagName3 = "grade";
System.out.println("解析单一对象学生----------------------------------------");
Map<String, String> stuMap = new HashMap<>();
stuMap.put("name", "name");
stuMap.put("age", "age");
stuMap.put("sex", "sex");
stuMap.put("address", "address");
Student students = ReadXML.readObjXml(xmlPath, tagName1, Student.class, stuMap);
System.out.println(students);
System.out.println("解析单一对象老师----------------------------------------");
Map<String, String> teaMap = new HashMap<>();
teaMap.put("id", "id");
teaMap.put("name", "teacherName");
teaMap.put("subject", "subject");
teaMap.put("salary", "salary");
Teacher teachers = ReadXML.readObjXml(xmlPath, tagName2, Teacher.class, teaMap);
System.out.println(teachers);
}
解析对象数组
对象成绩定义类
class Grade {
private long id;
private String stuName;
private String subject;
private double score;
@Override
public String toString() {
return "Grade{" +
"id='" + id + '\'' +
", studentName='" + stuName + '\'' +
", subject='" + subject + '\'' +
", score=" + score +
'}';
}
}
解析方法
/**
* 从XML文件中读取对象信息,并返回指定类型的对象列表。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @param clazz 目标类型的Class对象,用于类型安全的返回。
* @param mapping 属性名到XML标签的映射。
* @param <T> 泛型类型。
* @return 返回创建的对象实例列表。
*/
public static <T> List<T> readObjsXml(String xmlPath, String tagName, Class<T> clazz, Map<String, String> mapping) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找所有的顶层标签
NodeList topLevelNodes = document.getChildNodes();
// 创建对象列表
List<T> objects = new ArrayList<>();
// 遍历所有的顶层标签
for (int i = 0; i < topLevelNodes.getLength(); i++) {
Node topLevelNode = topLevelNodes.item(i);
if (topLevelNode.getNodeType() == Node.ELEMENT_NODE) {
Element topLevelElement = (Element) topLevelNode;
// 查找内部的 tagName 标签节点列表
NodeList internalNodes = topLevelElement.getElementsByTagName(tagName);
// 遍历所有匹配的节点
for (int j = 0; j < internalNodes.getLength(); j++) {
Element element = (Element) internalNodes.item(j);
// 使用反射创建对象实例
T instance = clazz.getDeclaredConstructor().newInstance();
// 设置对象属性
for (Map.Entry<String, String> entry : mapping.entrySet()) {
String propertyName = entry.getKey();
String xmlTagName = entry.getValue();
Node node = element.getElementsByTagName(xmlTagName).item(0);
if (node != null && node.getFirstChild() != null) {
String value = node.getFirstChild().getNodeValue();
// 设置属性值
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true); // 允许访问私有字段
if (field.getType() == Integer.class || field.getType() == int.class) {
field.setInt(instance, Integer.parseInt(value));
} else if (field.getType() == Long.class || field.getType() == long.class) {
field.setLong(instance, Long.parseLong(value));
} else if (field.getType() == Double.class || field.getType() == double.class) {
field.setDouble(instance, Double.parseDouble(value));
} else if (field.getType() == String.class) {
field.set(instance, value);
} else {
throw new IllegalArgumentException("Unsupported type for property: " + propertyName);
}
}
}
objects.add(instance);
}
}
}
return objects;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and create objects", e);
}
}
public static void main(String[] args) {
String xmlPath = "src/code/readXml/test.xml";
String tagName1 = "student";
String tagName2 = "teacher";
String tagName3 = "grade";
String tagName4 = "farm";
System.out.println("解析对象数组成绩----------------------------------------");
Map<String, String> mapping = new HashMap<>();
mapping.put("id", "id");
mapping.put("stuName", "studentName");
mapping.put("subject", "subject");
mapping.put("score", "score");
List<Grade> grades = ReadXML.readObjsXml(xmlPath, tagName3, Grade.class, mapping);
for (Grade grade : grades) {
System.out.println(grade);
}
}
完整代码
package code.readXml;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
class Grade {
private long id;
private String stuName;
private String subject;
private double score;
@Override
public String toString() {
return "Grade{" +
"id='" + id + '\'' +
", studentName='" + stuName + '\'' +
", subject='" + subject + '\'' +
", score=" + score +
'}';
}
}
class Teacher {
private int id;
private String name;
private String subject;
private double salary;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", id=" + id +
", subject='" + subject + '\'' +
", salary='" + salary + '\'' +
'}';
}
}
class Student {
private String name;
private int age;
private String sex;
private String address;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
public class ReadXML {
/**
* 从XML文件中读取单一标签的内容,并返回字符串。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @return 返回标签内的文本内容。
*/
public static String readStringTag(String xmlPath, String tagName) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找指定的标签
NodeList nodeList = document.getElementsByTagName(tagName);
if (nodeList.getLength() == 0) {
throw new IllegalArgumentException("No '" + tagName + "' element found in XML file.");
}
// 获取第一个匹配的节点
Node node = nodeList.item(0);
// 检查节点类型是否为元素节点
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
if (element.hasChildNodes()) {
Node childNode = element.getFirstChild();
if (childNode != null && childNode.getNodeType() == Node.TEXT_NODE) {
return childNode.getNodeValue();
}
}
}
throw new IllegalArgumentException("The '" + tagName + "' tag does not contain any text.");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and retrieve string content", e);
}
}
/**
* 从XML文件中读取对象信息,并返回指定类型的对象实例。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @param clazz 目标类型的Class对象,用于类型安全的返回。
* @param mapping 属性名到XML标签的映射。
* @param <T> 泛型类型。
* @return 返回创建的对象实例。
*/
public static <T> T readObjXml(String xmlPath, String tagName, Class<T> clazz, Map<String, String> mapping) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找指定标签名的节点列表
NodeList nodeList = document.getElementsByTagName(tagName);
if (nodeList.getLength() == 0) {
throw new IllegalArgumentException("No '" + tagName + "' element found in XML file.");
}
// 获取第一个匹配节点
Element element = (Element) nodeList.item(0);
// 使用反射创建对象实例
T instance = clazz.getDeclaredConstructor().newInstance();
// 设置对象属性
for (Map.Entry<String, String> entry : mapping.entrySet()) {
String propertyName = entry.getKey();
String xmlTagName = entry.getValue();
Node node = element.getElementsByTagName(xmlTagName).item(0);
if (node != null && node.getFirstChild() != null) {
String value = node.getFirstChild().getNodeValue();
// 设置属性值
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true); // 允许访问私有字段
if (field.getType() == Integer.class || field.getType() == int.class) {
field.setInt(instance, Integer.parseInt(value));
} else if (field.getType() == Long.class || field.getType() == long.class) {
field.setLong(instance, Long.parseLong(value));
} else if (field.getType() == Double.class || field.getType() == double.class) {
field.setDouble(instance, Double.parseDouble(value));
} else if (field.getType() == String.class) {
field.set(instance, value);
}
else {
throw new IllegalArgumentException("Unsupported type for property: " + propertyName);
}
}
}
return instance;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and create object", e);
}
}
/**
* 从XML文件中读取对象信息,并返回指定类型的对象列表。
*
* @param xmlPath XML文件的路径。
* @param tagName 要查询的XML标签名称。
* @param clazz 目标类型的Class对象,用于类型安全的返回。
* @param mapping 属性名到XML标签的映射。
* @param <T> 泛型类型。
* @return 返回创建的对象实例列表。
*/
public static <T> List<T> readObjsXml(String xmlPath, String tagName, Class<T> clazz, Map<String, String> mapping) {
try {
// 初始化DOM解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
// 解析XML文件
Document document = documentBuilder.parse(new File(xmlPath));
// 查找所有的顶层标签
NodeList topLevelNodes = document.getChildNodes();
// 创建对象列表
List<T> objects = new ArrayList<>();
// 遍历所有的顶层标签
for (int i = 0; i < topLevelNodes.getLength(); i++) {
Node topLevelNode = topLevelNodes.item(i);
if (topLevelNode.getNodeType() == Node.ELEMENT_NODE) {
Element topLevelElement = (Element) topLevelNode;
// 查找内部的 tagName 标签节点列表
NodeList internalNodes = topLevelElement.getElementsByTagName(tagName);
// 遍历所有匹配的节点
for (int j = 0; j < internalNodes.getLength(); j++) {
Element element = (Element) internalNodes.item(j);
// 使用反射创建对象实例
T instance = clazz.getDeclaredConstructor().newInstance();
// 设置对象属性
for (Map.Entry<String, String> entry : mapping.entrySet()) {
String propertyName = entry.getKey();
String xmlTagName = entry.getValue();
Node node = element.getElementsByTagName(xmlTagName).item(0);
if (node != null && node.getFirstChild() != null) {
String value = node.getFirstChild().getNodeValue();
// 设置属性值
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true); // 允许访问私有字段
if (field.getType() == Integer.class || field.getType() == int.class) {
field.setInt(instance, Integer.parseInt(value));
} else if (field.getType() == Long.class || field.getType() == long.class) {
field.setLong(instance, Long.parseLong(value));
} else if (field.getType() == Double.class || field.getType() == double.class) {
field.setDouble(instance, Double.parseDouble(value));
} else if (field.getType() == String.class) {
field.set(instance, value);
} else {
throw new IllegalArgumentException("Unsupported type for property: " + propertyName);
}
}
}
objects.add(instance);
}
}
}
return objects;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to parse XML and create objects", e);
}
}
public static void main(String[] args) {
String xmlPath = "src/code/readXml/test.xml";
String tagName1 = "student";
String tagName2 = "teacher";
String tagName3 = "grade";
String tagName4 = "farm";
System.out.println("解析字符串----------------------------------------");
String farmContent = ReadXML.readStringTag(xmlPath, tagName4);
System.out.println("Farm content: " + farmContent);
System.out.println("解析单一对象学生----------------------------------------");
Map<String, String> stuMap = new HashMap<>();
stuMap.put("name", "name");
stuMap.put("age", "age");
stuMap.put("sex", "sex");
stuMap.put("address", "address");
Student students = ReadXML.readObjXml(xmlPath, tagName1, Student.class, stuMap);
System.out.println(students);
System.out.println("解析单一对象老师----------------------------------------");
Map<String, String> teaMap = new HashMap<>();
teaMap.put("id", "id");
teaMap.put("name", "teacherName");
teaMap.put("subject", "subject");
teaMap.put("salary", "salary");
Teacher teachers = ReadXML.readObjXml(xmlPath, tagName2, Teacher.class, teaMap);
System.out.println(teachers);
System.out.println("解析对象数组成绩----------------------------------------");
Map<String, String> mapping = new HashMap<>();
mapping.put("id", "id");
mapping.put("stuName", "studentName");
mapping.put("subject", "subject");
mapping.put("score", "score");
List<Grade> grades = ReadXML.readObjsXml(xmlPath, tagName3, Grade.class, mapping);
for (Grade grade : grades) {
System.out.println(grade);
}
}
}