转载请标明原创:https://me.csdn.net/jxysgzs
java使用Hutool功具,完成基本的对xml,XML文本字符串的新增节点数据,修改节点数据,查询节点数据
- https://blog.csdn.net/jxysgzs/article/details/120867068?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168316653016800192259631%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=168316653016800192259631&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-120867068-null-null.blog_rank_default&utm_term=xml&spm=1018.2226.3001.4450
首先定义一个xml格式的字符串。
ps:用流读取成字符串的也一样,这里为了方便直接定义了。
<forms version="2.1">
<formExport>
<summary id="1132755668421070367" name="formmain_0031"/>
<definitions>
<column id="field0001" type="0" name="field1" length="255"/>
<column id="field0002" type="0" name="field2" length="256"/>
</definitions>
<values>
<column name="field1">
<value>
建行一世
</value>
</column>
<column name="field2">
<value>
CSDN
</value>
</column>
</values>
<subForms/>
</formExport>
</forms>
2. 增删改查
子标签的第一个标签
一、查询
一、查询
-
查询标签内的属性。
例:获取<definitions>标签中第一个标签<column >属性length的值
String xmlData="上面规定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG=XmlUtil.getRootElement(document);
//打印节点名称
System.out.println(elementG.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
System.out.println(elementZ.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ1=XmlUtil.getElement(elementZ,"definitions");
System.out.println(elementZ1.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ2=XmlUtil.getElement(elementZ1,"column");
System.out.println(elementZ2.getTagName());
//读取属性length
System.out.println(elementZ2.getAttribute("length"));
打印结果
forms
formExport
definitions
column
255
查询标签中的文本
查询一对标签中的文本
例:获取标签中第一个标签下的所包含的文本
//String xmlData = "上面规定的xml字符串";
Document document = XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG = XmlUtil.getRootElement(document);
//打印节点名称
System.out.println(elementG.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ = XmlUtil.getElement(elementG, "formExport");
System.out.println(elementZ.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ_1 = XmlUtil.getElement(elementZ, "values");
System.out.println(elementZ_1.getTagName());
//获取下层节点(该方法默认取第一个)
Element elementZ_2 = XmlUtil.getElement(elementZ_1, "column");
System.out.println(elementZ_2.getTagName());
//获取到所有子标签
NodeList nodeList = elementZ_2.getElementsByTagName("value");
for (int i = 0; i < nodeList.getLength(); i++) {
//打印标签的文本
System.out.println(nodeList.item(i).getTextContent());
}
forms
formExport
values
column
建行一世
使用路径解析
- Element对象目前仅能支持一层一层的向下解析,所以请不要跳级去做查询,否则会报null。如果想直接获取到某个标签的文本,在有准确定位的情况下可以直接写出路径获取,但是如果该层级存在相同的标签则只获取第一个标签的数据。
String xmlData="上面规定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG=XmlUtil.getRootElement(document);
//打印节点名称
System.out.println(elementG.getTagName());
//通过固定路径获取到数据
Object bString = XmlUtil.getByXPath("//forms/formExport/values/column/value", document, XPathConstants.STRING);
System.out.println("value元素节点值:"+bString);
打印结果
forms
value元素节点值:
建行一世
查询并新增
二、查询新增一个标签并赋值。
例:给标签中第一个标签下再度添加一个标签,所包含的文本为:从零开始
String xmlData="上面规定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG=XmlUtil.getRootElement(document);
//打印节点名称
//获取下层节点(该方法默认取第一个)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//获取下层节点(该方法默认取第一个)
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//获取下层节点(该方法默认取第一个)
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
//创建一个标签
Element elementItem = document.createElement("value");
//赋值
elementItem.setTextContent("从零开始");
//放到某个标签下面
elementZ_2.appendChild(elementItem);
//获取到所有子标签
NodeList nodeList=elementZ_2.getElementsByTagName("value");
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印标签的文本
System.out.println(nodeList.item(i).getTextContent());
}
System.out.println(XmlUtil.toStr(document));
建行一世
从零开始
<?xml version="1.0" encoding="UTF-8" standalone="no"?><forms version="2.1">
<formExport>
<summary id="1132755668421070367" name="formmain_0031"/>
<definitions>
<column id="field0001" length="255" name="field1" type="0"/>
<column id="field0002" length="256" name="field2" type="0"/>
</definitions>
<values>
<column name="field1">
<value>
建行一世
</value>
<value>从零开始</value></column>
<column name="field2">
<value>
CSDN
</value>
</column>
</values>
<subForms/>
</formExport>
</forms>
修改标签
三、修改一个标签数据。
例:给<values>标签中第一个标签<column>下的第一个<value>标签修改成:张三丰
String xmlData="上面规定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG=XmlUtil.getRootElement(document);
//打印节点名称
//获取下层节点(该方法默认取第一个)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//获取下层节点(该方法默认取第一个)
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//获取下层节点(该方法默认取第一个)
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
//获取到所有子标签
NodeList nodeList=elementZ_2.getElementsByTagName("value");
//第一次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印标签的文本
System.out.println(nodeList.item(i).getTextContent());
}
//修改
for (int i = 0; i <nodeList.getLength() ; i++) {
//这里进行修改*******************
nodeList.item(i).setTextContent("张三丰");
}
//第二次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印标签的文本
System.out.println(nodeList.item(i).getTextContent());
}
打印结果
建行一世
张三丰
3. 工具类
提示! 上面看上去有些同学肯定觉得比较复杂吧,这里代码量确实多,主要也是为了让大家能更快的理解并上手,后续同学们可以自己去封装一下好用的方法,这样就会简洁很多。
我这里临时使用写了个dome,需要的同学们拿走吧。
import cn.hutool.core.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李建
* @version 1.0
* @date 2021/10/20 0020 15:37
*/
public class XmlStateUtil {
/**
* 查询element之下所有层级的文本数据
*
* @param element 根节点(上级节点)
* @param name 需要查询的节点名称,不需要加<></>
* @return
*/
public static List<String> getElementValueByName(Element element, String name) {
//从节点里,获取这个 子节点
NodeList nodeList = element.getElementsByTagName(name);
List<String> stringList = new ArrayList<>();
//遍历 放入lists
for (int i = 0; i < nodeList.getLength(); i++) {
stringList.add(nodeList.item(i).getTextContent());
}
return stringList;
}
/**
* 编译xml字符串,查询所有层级的文本数据
*
* @param xmlData xml字符串
* @param name 需要查询的节点名称,不需要加<></>
* @return
*/
public static List<String> getXmlValueByName(String xmlData, String name) {
//xml 转成 document
Document document = XmlUtil.parseXml(xmlData);
//获得XML文档根节点
Element elementG = XmlUtil.getRootElement(document);
return getElementValueByName(elementG, name);
}
/**
* 给一个节点下添加一个新的节点并赋值
*
* @param document 核心xml主要数据
* @param element 需要添加节点的节点
* @param tagName 节点名称
* @param value 节点文本
* @return
*/
public static void setXmlStrByElementAndText(Document document, Element element, String tagName, String value) {
//在文档下,创建 Element
Element elementItem = document.createElement(tagName);
//设置上 内容
elementItem.setTextContent(value);
//添加到 对象列表
element.appendChild(elementItem);
}
/**
* 根据表达式,获取最终目录下的第一个节点
* @param document 核心xml主数据
* @param url 表达式 例://forms/formExport/definitions/column
* @param number 按顺序第一几个节点,最小为第一个
* @return
*/
public static Element getElementByUrl(Document document, String url, int number) {
//获取到这个 nodeList
NodeList nodeList=XmlUtil.getNodeListByXPath(url,document);
//转成 对象list
List<Element> elementList=XmlUtil.transElements(nodeList);
//获取 出这个 节点
return elementList.get(number > 0 ? number : 0);
}
}
工具类使用
@Test
void testUtil() {
for (String value : XmlStateUtil.getXmlValueByName(xmlData, "value")) {
System.out.println(value);
}
}
建行一世
CSDN
xmlToBean
xml
- result里包含,cars
- cars里包含 car
- car就是 对底层的对象了
- cars里包含 car
<result>
<cars lineid="63002">
<car>
<vehicle>沪A38606D</vehicle>
<time>13:35</time>
</car>
<car>
<vehicle>沪A01308D</vehicle>
<time>13:45</time>
</car>
<car>
<vehicle>沪A38505D</vehicle>
<time>13:54</time>
</car>
</cars>
</result>
外层对象里 包含 cars
@Data
//@XmlRootElement(name = "result")
public class DepartCarResult {
//@XmlElement(name = "cars")
private CarListModel cars;
}
cars里 包含多个car
@Data
//@XmlRootElement(name = "cars")
public class CarListModel {
// @XmlElement(name = "car")
private List<Car> car;
}
car就是最底层的对象,包含多个属性
@Data
//@XmlRootElement(name = "car")
public class Car {
//@XmlAttribute(name = "vehicle")
private String vehicle;
//@XmlAttribute(name = "time")
private String time;
}
进行测试
//获取文档
Document document = XmlUtil.parseXml(xmlData);
//获取根节点
Element elementG = XmlUtil.getRootElement(document);
//方式1:使用根节点下的直接 转成对象
DepartCarResult departCarResult = XmlUtil.xmlToBean(elementG, DepartCarResult.class);
//方式2:获取 根节点下 cars 节点
Element carsElement = XmlUtil.getElement(elementG, "cars");
//cars 节点是个 List,每一个对象为 car
CarListModel carListModel = XmlUtil.xmlToBean(carsElement, CarListModel.class);