欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中操作Xml使用方法備忘錄(Hutool工具類XmlUtil、XStream)

 更新時間:2023年11月15日 14:52:59   作者:劃]破  
這篇文章主要給大家介紹了關(guān)于Java中操作Xml使用方法(Hutool工具類XmlUtil、XStream)的相關(guān)資料,XMLUtil是一個工具類,主要用于讀取XML配置文件并提供相應(yīng)的操作方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

1. Hutool中XmlUtil的使用簡介

# 說明1: XmlUtil只是w3c dom的簡單工具化封裝,減少操作dom的難度,
#         如果項(xiàng)目對XML依賴較大,依舊推薦Dom4j框架
# 說明2:JDK已經(jīng)封裝有XML解析和構(gòu)建工具:w3c dom
#         Hutool中XmlUtil簡化XML的創(chuàng)建、讀、寫
1. 讀取XML
    讀取XML分為兩個方法:

    XmlUtil.readXML 讀取XML文件
    XmlUtil.parseXml 解析XML字符串為Document對象
    
2. 寫XML
    XmlUtil.toStr     將XML文檔轉(zhuǎn)換為String
    XmlUtil.toFile     將XML文檔寫入到文件
    
3. 創(chuàng)建XML
    XmlUtil.createXml 創(chuàng)建XML文檔, 創(chuàng)建的XML默認(rèn)是utf8編碼,
    修改編碼的過程是在toStr和toFile方法里,既XML在轉(zhuǎn)為文本的時候才定義編碼。

4. XML讀取操作
    通過以下工具方法,可以完成基本的節(jié)點(diǎn)讀取操作。
        XmlUtil.cleanInvalid 除XML文本中的無效字符
        XmlUtil.getElements 根據(jù)節(jié)點(diǎn)名獲得子節(jié)點(diǎn)列表
        XmlUtil.getElement 根據(jù)節(jié)點(diǎn)名獲得第一個子節(jié)點(diǎn)
        XmlUtil.elementText 根據(jù)節(jié)點(diǎn)名獲得第一個子節(jié)點(diǎn)
        XmlUtil.transElements 將NodeList轉(zhuǎn)換為Element列表
        
5. XML與對象轉(zhuǎn)換
    writeObjectAsXml 將可序列化的對象轉(zhuǎn)換為XML寫入文件,已經(jīng)存在的文件將被覆蓋。
    readObjectFromXml 從XML中讀取對象。
        注意 這兩個方法嚴(yán)重依賴JDK的XMLEncoder和XMLDecoder,
        生成和解析必須成對存在(遵循固定格式),普通的XML轉(zhuǎn)Bean會報(bào)錯。

6. Xpath操作
    createXPath 創(chuàng)建XPath
    getByXPath     通過XPath方式讀取XML節(jié)點(diǎn)等信息

2. Hutool中XmlUtil快速讀取Xml字符串某個節(jié)點(diǎn)值 [簡單取值時,推薦使用]

2-1 Hutool工具包Maven依賴和測試Xml字符串如下

<!-- 引入Hutool的Maven依賴 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>
<!-- 下方測試用的Xml字符串 -->
<?xml version="1.0" encoding="utf-8"?>
<returnsms> 
  <returnstatus>Success(成功)</returnstatus>  
  <message>ok</message>  
  <remainpoint>1490</remainpoint>  
  <taskID>885</taskID>  
  <successCounts>1</successCounts> 
</returnsms>

2-2 讀取Xml中的節(jié)點(diǎn)的值

Document docResult=XmlUtil.readXML(xmlFile);
// 結(jié)果為“ok”
Object value = XmlUtil.getByXPath("http://returnsms/message", docResult, XPathConstants.STRING);

// 說明:Element對象目前僅能支持一層一層的向下解析,所以請不要跳級去做查詢,
//		 否則會報(bào)null。如果想直接獲取到某個標(biāo)簽的文本,在有準(zhǔn)確定位的情況下
//		 可以直接寫出路徑獲取,
//		 但是如果該層級存在相同的標(biāo)簽則只獲取第一個標(biāo)簽的數(shù)據(jù)。
String xmlData="xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//通過固定路徑獲取到數(shù)據(jù)
Object bString = XmlUtil.getByXPath("http://root/base/message/event_no", document, XPathConstants.STRING);
System.out.println("event_no元素節(jié)點(diǎn)值:"+bString);

3. Hutool中XmlUtil詳細(xì)操作示例

3-1 Xml示例字符串如下

<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>
                    中國人民
                </value>
            </column>
        </values>
        <subForms/>
    </formExport>
</forms>

3-2 查詢標(biāo)簽內(nèi)的屬性

// 例: 獲取<definitions>標(biāo)簽中第一個標(biāo)簽<column >屬性length的值

String xmlData="上面規(guī)定的xml字符串";  // 測試時自己替換下
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//打印節(jié)點(diǎn)名稱
System.out.println(elementG.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
System.out.println(elementZ.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ1=XmlUtil.getElement(elementZ,"definitions");
System.out.println(elementZ1.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ2=XmlUtil.getElement(elementZ1,"column");
System.out.println(elementZ2.getTagName());


//讀取屬性length
System.out.println(elementZ2.getAttribute("length"));

3-3 查詢一對標(biāo)簽中的文本

// 例:獲取<values>標(biāo)簽中第一個標(biāo)簽<column>下的<value>所包含的文本,可直接看最后一行

// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================

//獲取到所有子標(biāo)簽    // Value返回的時NodeList,遍歷獲取即可
NodeList nodeList=elementZ_2.getElementsByTagName("value");
for (int i = 0; i <nodeList.getLength() ; i++) {
    //打印標(biāo)簽的文本
    System.out.println(nodeList.item(i).getTextContent());
}

3-4 查詢Xml后,再新增一個標(biāo)簽并賦值

// 例:給<values>標(biāo)簽中第一個標(biāo)簽<column>下再度添加一個<value>標(biāo)簽,所包含的文本為:從零開始

// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================

//創(chuàng)建一個標(biāo)簽
Element elementItem = document.createElement("value");
//賦值
elementItem.setTextContent("從零開始");
//放到某個標(biāo)簽下面
elementZ_2.appendChild(elementItem);
//獲取到所有子標(biāo)簽
NodeList nodeList=elementZ_2.getElementsByTagName("value");
for (int i = 0; i <nodeList.getLength() ; i++) {
    //打印標(biāo)簽的文本
    System.out.println(nodeList.item(i).getTextContent());
}
System.out.println(XmlUtil.toStr(document));

// 打印的結(jié)果: 在<value>建行一世</value>后,新增了一個<value>從零開始</value>

3-5 修改一個標(biāo)簽數(shù)據(jù)

// 例:給<values>標(biāo)簽中第一個標(biāo)簽<column>下的第一個<value>標(biāo)簽修改成:張三豐

// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個)
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================

//獲取到所有子標(biāo)簽
NodeList nodeList=elementZ_2.getElementsByTagName("value");
//第一次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
    //打印標(biāo)簽的文本
    System.out.println(nodeList.item(i).getTextContent());
}
//修改
for (int i = 0; i <nodeList.getLength() ; i++) {
    // ******************* 這里進(jìn)行修改 ********************
    nodeList.item(i).setTextContent("張三豐");
}
//第二次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
    //打印標(biāo)簽的文本
    System.out.println(nodeList.item(i).getTextContent());
}
// 打印輸出結(jié)果: 
//	第一次打印輸出為:  建行一世
//	第二次打印輸出為:  張三豐

4 依賴Hutool再次封裝的工具類XmlUtil,實(shí)現(xiàn)xml-map、map-xml、xml-json功能

// 作用:
//     1.xml轉(zhuǎn)map
//     2.xml轉(zhuǎn)json
//     3.map轉(zhuǎn)xml

4-1 需要添加的依賴

<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.15</version>
</dependency>
 
<dependency>
   <groupId>org.dom4j</groupId>
   <artifactId>dom4j</artifactId>
   <version>2.1.3</version>
</dependency>

4-2 工具類XmlUtil代碼

4-2-1 用到的一個枚舉XmlSort如下:

import java.util.HashMap;
import java.util.LinkedHashMap;
 
/**
 * xml解析順序是否有序
 * @author ASen
 */
 
public enum XmlSort{
    /**
     * 有序
     */
    SORT(LinkedHashMap.class,"有序"),
    /**
     * 無序
     */
    NO_SORT(HashMap.class,"無序");
 
    /**
     *  創(chuàng)建的map字節(jié)碼對象
     */
    private final Class<?> mapClass;
 
    /**
     * 順序名稱
     */
    private final String message ;
 
    XmlSort(Class<?> mapClass, String message) {
        this.mapClass = mapClass;
        this.message = message;
    }
 
    public Class<?> getMapClass() {
        return mapClass;
    }
 
    public String getMessage() {
        return message;
    }
}

4-2-2 XmlUtil.java如下

package com.asen.demo.util;
 
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.asen.demo.constant.XmlSort;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultDocument;
import org.dom4j.tree.DefaultElement;
 
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
 
/**
 * xml解析幫組類
 * @author asen
 * @date 2022/1/10 15:17
 */
public class XmlUtil {
 
    /**
     * 標(biāo)簽屬性
     */
    private final static String TAG_ATTR = "attr";
 
    /**
     * 創(chuàng)建的map類型
     */
    private XmlSort xmlSort = XmlSort.NO_SORT;
 
    /**
     * map to xml
     * @param map map對象
     * @return xml 字符串
     */
    public String mapToXml(Map<String,Object> map) {
        if(map.size() != 1){
            throw new RuntimeException("map根節(jié)點(diǎn)長度不為1");
        }
        String key = "";
        for (String str : map.keySet()) {
            key = str ;
        }
        //  創(chuàng)建根節(jié)點(diǎn)
        Element rootElement = new DefaultElement(key);
        Document document = new DefaultDocument(rootElement);
        Element node = document.getRootElement();
        Object obj = map.get(key);
        // 斷言
        Assert.isAssignable(Map.class,obj.getClass());
        mapNodes(node,(Map<String, Object>)obj);
        return document.asXML();
    }
 
    /**
     * 父類節(jié)點(diǎn)已經(jīng)創(chuàng)建, map 包含父類
     * @param node node
     * @param map map
     */
    public void mapNodes(Element node, Map<String, Object> map) {
        map.forEach((k,v)->{
            Object obj = map.get(k);
            // 給當(dāng)前父類添加屬性
            if(TAG_ATTR.equals(k)){
                Assert.isAssignable(Map.class,obj.getClass());
                Map<String,Object> tagMap = (Map<String,Object>) obj;
                tagMap.forEach((tagKey,tagValue)->{
                    node.addAttribute(tagKey, (String) tagValue);
                });
                return ;
            }
            if(obj instanceof Map){
                Element newElement = node.addElement(k);
                // map 處理
                Map<String,Object> childMap = (Map<String,Object>) obj;
                mapNodes(newElement,childMap);
            }else if (obj instanceof String){
                Element newElement = node.addElement(k);
                newElement.setText((String) v);
            } else if (obj instanceof List) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) obj;
                list.forEach(itemMap->{
                    Element newElement = node.addElement(k);
                    mapNodes(newElement,itemMap);
                });
            }
        });
    }
 
 
    /**
     * 讀取xml文件,返回json字符串
     *
     * @param fileName 文件路徑
     * @return json字符串
     * @throws DocumentException 異常
     */
    public String xmlToJson(String fileName) throws DocumentException {
        Map<String, Object> xmlMap = xmlToMap(fileName);
        return JSONUtil.toJsonStr(xmlMap);
    }
 
    /**
     * 讀取xml文件,返回map對象
     *
     * @param fileName 文件路徑
     * @return map對象
     * @throws DocumentException 異常
     */
    public Map<String, Object> xmlToMap(String fileName) throws DocumentException {
        // 創(chuàng)建saxReader對象
        SAXReader reader = new SAXReader();
        // 通過read方法讀取一個文件 轉(zhuǎn)換成Document對象
        Document document = reader.read(new File(fileName));
        //獲取根節(jié)點(diǎn)元素對象
        Element node = document.getRootElement();
        //遍歷所有的元素節(jié)點(diǎn)
        Map<String, Object> map = getNewMap();
        // 處理節(jié)點(diǎn)
        listNodes(node, map);
        return map;
    }
 
 
    /**
     * 遍歷當(dāng)前節(jié)點(diǎn)元素下面的所有(元素的)子節(jié)點(diǎn)
     *
     * @param node node
     */
    public void listNodes(Element node, Map<String, Object> map) {
        Map<String, Object> xiaoMap = getNewMap();
        String nodeKey = node.getName();
        // 獲取當(dāng)前節(jié)點(diǎn)的所有屬性節(jié)點(diǎn)
        List<Attribute> list = node.attributes();
        // 遍歷屬性節(jié)點(diǎn)
        Map<String, Object> attrMap = getNewMap();
        for (Attribute attr : list) {
            attrMap.put(attr.getName(), attr.getValue());
        }
        if (ObjectUtil.isNotEmpty(attrMap)) {
            xiaoMap.put(TAG_ATTR, attrMap);
        }
 
        // 當(dāng)前節(jié)點(diǎn)下面子節(jié)點(diǎn)迭代器
        Iterator<Element> it = node.elementIterator();
 
        if (!("".equals(node.getTextTrim())) || !it.hasNext()) {
            map.put(nodeKey, node.getTextTrim());
        }else{
            // 不為空
            if (ObjectUtil.isEmpty(map.get(nodeKey))) {
                map.put(nodeKey, xiaoMap);
            } else {
                List<Map<String, Object>> childList = null;
                // 獲取原來的
                Object obj = map.get(nodeKey);
                if (obj instanceof Iterable) {
                    // 非第一個
                    childList = (List<Map<String, Object>>) obj;
                    childList.add(xiaoMap);
                } else if (obj instanceof Map) {
                    // 第一個
                    Map<String, Object> childMap = (Map<String, Object>) obj;
                    childList = new ArrayList<>();
                    childList.add(childMap);
                    childList.add(xiaoMap);
                }
                // 添加新的
                map.put(nodeKey, childList);
            }
        }
 
        // 遍歷
        while (it.hasNext()) {
            // 獲取某個子節(jié)點(diǎn)對象
            Element e = it.next();
            // 對子節(jié)點(diǎn)進(jìn)行遍歷
            listNodes(e, xiaoMap);
        }
    }
 
    /**
     * 獲取一個新的map對象
     *
     * @return map對象
     */
    private Map<String, Object> getNewMap() {
        Object obj = null;
        try {
            obj = xmlSort.getMapClass().newInstance();
            if (obj instanceof Map) {
                return (Map<String, Object>) obj;
            }
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 設(shè)置是否排序
     *
     * @param xmlSort 是否排序?qū)ο?
     */
    public void setXmlSort(XmlSort xmlSort) {
        this.xmlSort = xmlSort;
    }
}

5 JavaBean與Xml互轉(zhuǎn)_使用XStream實(shí)現(xiàn),很實(shí)用 [強(qiáng)烈推薦使用]

說明:

相對于JAXB,XStream更簡潔一些。

常用注解:

  • @XStreamAlias:定義xml節(jié)點(diǎn)名
  • @XStreamAsAttribute:把字段節(jié)點(diǎn)設(shè)置成屬性

5-1 引入XStream依賴

<dependency>
	<groupId>com.thoughtworks.xstream</groupId>
	<artifactId>xstream</artifactId>
	<version>1.4.19</version>
</dependency>

5-2 工具類XStreamXmlBeanUtil

import com.thoughtworks.xstream.XStream;
 
/**
 * XStream 實(shí)現(xiàn)bean與xml之間相互轉(zhuǎn)換
 */
public class XStreamXmlBeanUtil {
    /**
     * JavaBean轉(zhuǎn)XML
     * @param bean - JavaBean
     * @return - XML
     */
    public static String toXml(Object bean) {
        return initXStream(bean.getClass()).toXML(bean);
    }
 
    /**
     * XML轉(zhuǎn)JavaBean
     * @param xml - XML
     * @param beanClazz - JavaBean Class
     * @param <T>
     * @return - JavaBean
     */
    @SuppressWarnings("unchecked")
    public static <T> T fromXml(String xml, Class<T> beanClazz) {
        return (T) initXStream(beanClazz).fromXML(xml);
    }
 
    private static XStream initXStream(Class<?> beanClazz) {
        XStream x = new XStream();
		x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,TimeZone.getTimeZone("GMT+8")));
		
        //不使用默認(rèn)的類加載器,需要手動設(shè)置類加載器
        x.setClassLoader(beanClazz.getClassLoader());
        x.processAnnotations(beanClazz);
        x.allowTypesByRegExp(new String[]{".*"});
        // 開起注解功能
        x.autodetectAnnotations(true);
        // 忽律未知字段
        x.ignoreUnknownElements();
        return x;
    }
}

5-3 使用實(shí)例

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
public class Test {
    public static void main(String[] args) {
        // 1. 普通bean與Xml互轉(zhuǎn)
        User user = new User("貂蟬", 18, "女");
        System.out.println("============普通bean轉(zhuǎn)Xml===============");
        String xml = XStreamXmlBeanUtil.toXml(user);
        System.out.println(xml);
		System.out.println("============Xml轉(zhuǎn)普通bean===============");
        System.out.println(XStreamXmlBeanUtil.fromXml(xml, User.class));
 
 		// 2. 繼承bean與Xml互轉(zhuǎn)
        Child child = new Child("吃糖葫蘆");
        child.setName("葫蘆娃");
        child.setAge(2);
        child.setGender("男");
        child.setHobby("打游戲");
 
        System.out.println("============繼承bean轉(zhuǎn)Xml===============");
        xml = XStreamXmlBeanUtil.toXml(child);
        System.out.println(xml);
        System.out.println("============Xml轉(zhuǎn)繼承bean====");
		// 生成的Xml僅有Child的屬性hobby,但轉(zhuǎn)后后的Child對象,父屬性都是有值的;
        System.out.println(XStreamXmlBeanUtil.fromXml(xml, Child.class));  
        System.out.println("============Xml轉(zhuǎn)繼承bean,測試轉(zhuǎn)換后,父屬性、自身屬性是否有值====");
        Child c2 = XStreamXmlBeanUtil.fromXml(xml, Child.class);
        System.out.println( "11111==" + c2.getName() + c2.getGender() + c2.getHobby());
		
		// 輸出內(nèi)容如下:
		//        ============普通bean轉(zhuǎn)Xml===============
		//        <Women>
		//          <name>貂蟬</name>
		//          <age>18</age>
		//          <gender>女</gender>
		//        </Women>
		//        ============Xml轉(zhuǎn)普通bean===============
		//        XmlTest.User(name=貂蟬, age=18, gender=女)
		//        ============繼承bean轉(zhuǎn)Xml===============
		//        <User>
		//          <name>葫蘆娃</name>
		//          <age>2</age>
		//          <gender>男</gender>
		//          <hobby>打游戲</hobby>
		//        </User>
		//        ============Xml轉(zhuǎn)繼承bean====
		//        XmlTest.Child(hobby=打游戲)
		//        11111==葫蘆娃男打游戲 
    }
}
 
@Data
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("Women")
class User {
    private String name;
    private int age;
    private String gender;
}
 
@NoArgsConstructor
@AllArgsConstructor
@Data
@XStreamAlias("User")
class Child extends User {
    private String hobby;
}

5-4 關(guān)于XStream更詳細(xì)的使用,如設(shè)置別名、設(shè)置屬性、隱藏集合根節(jié)點(diǎn)等,請參考如下博文

XStream使用詳解

總結(jié)

到此這篇關(guān)于Java中操作Xml使用方法備忘錄的文章就介紹到這了,更多相關(guān)Java操作Xml使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論