salesforce 零基礎學習(三十二)通過Streams和DOM方式讀寫XML


有的時候我們需要對XML進行讀寫操作,常用的XML操作主要有Streams和DOM方式。

一.Streams方式

Streams常用到的類主要有兩個XmlStreamReader 以及XmlStreamWriter。

XmlStreamReader:此種讀取方式的讀的特點為從上而下讀,下圖是根據reader的EventType自上而下的運行步驟。

 

我們將此xml讀取后封裝到一個Goods的List中,Goods包括item,name以及type屬性,代碼如下:

/*
* 假定目前XML數據樣式為:
*<?xml version="1.0"?>
*<goodsList>
*    <goods item="1">
*        <name>華為手機</name>
*        <type>華為</type>
*    </goods>
*    <goods item="2">
*        <name>小米手機</name>
*        <type>小米</type>
*    </goods>
*</goodsList>
* 需要將xml解析成Goods的一個List
*/
public class XmlReaderController {
    public class Goods {
        public String item{get;set;}
        public String name{get;set;}
        public String type{get;set;}
    }
    
    public List<Goods> getGoodsListByXmlFile(String goodsXml) {
        XmlStreamReader reader = new XmlStreamReader(goodsXml);
        Boolean flagXmlEnd = true;
        List<Goods> goodsList = new List<Goods>();
        while(flagXmlEnd) {
            Goods tempGoods;
            if(reader.getEventType() == XmlTag.START_ELEMENT) {
                if(reader.getLocalName().equalsIgnoreCase('goods')) {
                    tempGoods = getGoods(reader);
                }
            }
            
            if(reader.hasNext()) {
                reader.next();
            } else {
                flagXmlEnd = false;
                break;
            }
            if(tempGoods != null) {
                goodsList.add(tempGoods);
            }
        }
        return goodsList;
    }
    
    
    Goods getGoods(XmlStreamReader reader) {
        Goods tempGoods = new Goods();
        tempGoods.item = reader.getAttributeValue(null,'item');
        Boolean flagIsLoop = true;
        while(flagIsLoop) {
            if(reader.hasNext()) {
                reader.next();
                if(reader.getEventType() == XmlTag.START_ELEMENT) {
                    if(reader.getLocalName().equalsIgnoreCase('name')) {
                        reader.next();
                        tempGoods.name = reader.getText();
                    } else if(reader.getLocalName().equalsIgnoreCase('type')) {
                        reader.next();
                        tempGoods.type = reader.getText();
                    }
                }
                if(reader.getEventType() == XmlTag.END_ELEMENT && reader.getLocalName().equalsIgnoreCase('goods')) {
                    flagIsLoop = false;
                    break;
                }
            } else {
                flagIsLoop = false;
                break;
            }
        }
        return tempGoods;
    }
}

在匿名塊測試方法:

String goodsXml = '<?xml version="1.0"?>' +
        '<goodsList>' +
            '<goods item="1">' +
                '<name>華為手機</name>' +
                '<type>華為</type>' +
            '</goods>' +
            '<goods item="2">' +
                '<name>小米手機</name>' +
                '<type>小米</type>' +
            '</goods>' +
        '</goodsList>';
List<XmlReaderController.Goods> goodsList = new XmlReaderController().getGoodsListByXmlFile(goodsXml);
System.debug(JSON.serialize(goodsList));

顯示結果:

[
{
"type":"華為",
"name":"華為手機",
"item":"1"
},
{
"type":"小米",
"name":"小米手機",
"item":"2"
}

 XmlStreamWriter:處理過程同XmlStreamReader,需要從上到下進行寫入,例如如果寫出上述的xml文件,需要先startDocument,然后再startElement.....要注意每個start需要對應相應的end方法。

public class XmlWriterController {
    
    public static void writeXml() {
        XmlStreamWriter writer = new XmlStreamWriter();
        writer.writeStartDocument('utf-8','1.0');
        writer.writeComment('goodsList start here');
        writer.writeStartElement('','goodsList','http://www.goods.com');
        writer.writeNamespace('', 'http://www.goods.com'); 
        writer.writeStartElement(null,'goods',null);
        writer.writeAttribute(null,null,'item','1');
        writer.writeStartElement(null,'name',null);
        writer.writeCharacters('華為手機');
        writer.writeEndElement();
        writer.writeStartElement(null,'type',null);
        writer.writeCharacters('華為');
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeStartElement(null,'goods',null);
        writer.writeAttribute(null,null,'item','2');
        writer.writeStartElement(null,'name',null);
        writer.writeCharacters('小米手機');
        writer.writeEndElement();
        writer.writeStartElement(null,'type',null);
        writer.writeCharacters('小米');
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndDocument();
        system.debug(writer.getXmlString());
    }
}

 二.Dom解析

dom解析原理同java對於dom解析相同,這里,goodsList作為根節點,goodsList的子節點有goods1,goods.他們分別有屬性item1和item2,goods1以及goods2又分別有相應的子節點。

通過dom方式將上述xml解析成Goods的List。

public class DomXmlController {
    public class Goods {
        String item{get;set;}
        String name{get;set;}
        String type{get;set;}
    }
    public List<Goods> getGoodsViaXmlDom(String xmlString) {
        Dom.Document document = new Dom.Document();
        document.load(xmlString);
        Dom.XmlNode rootElement = document.getRootElement();
        List<Goods> goodsList = new List<Goods>();
        for(Dom.XmlNode node : rootElement.getChildElements()) {
            if(node.getName().equalsIgnoreCase('goods')) {
                Goods tempGoods = new Goods();
                tempGoods = getGoodsNameAndType(node);
                tempGoods.item = node.getAttribute('item',null);
                goodsList.add(tempGoods);
            }
        }
        
        return goodsList;
    }
    
    Goods getGoodsNameAndType(Dom.XmlNode parentNode) {
        transient Goods tempGoods = new Goods();
        for(Dom.XmlNode node : parentNode.getChildElements()) {
            if(node.getName().equalsIgnoreCase('name')) {
                tempGoods.name = node.getText();
            } else if(node.getName().equalsIgnoreCase('type')) {
                tempGoods.type = node.getText();
            }
        }
        return tempGoods;
    }
}

匿名塊測試內容如下:

String goodsXml = '<?xml version="1.0"?>' +
        '<goodsList>' +
            '<goods item="1">' +
                '<name>華為手機</name>' +
                '<type>華為</type>' +
            '</goods>' +
            '<goods item="2">' +
                '<name>小米手機</name>' +
                '<type>小米</type>' +
            '</goods>' +
            
        '</goodsList>';
System.debug(JSON.serialize(new DomXmlController().getGoodsViaXmlDom(goodsXml)));

顯示結果:

總結:apex對於xml操作和java很類似,或者說大部分都是從java過來的,如果java解析xml很嫻熟情況下,使用apex解析xml只需要看看方法就OK了。本篇只是描述最簡單的xml操作,篇中好多方法沒有使用到,有興趣的或者想深入的可以自己看一下相關的api。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM