有的时候我们需要对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。

salesforce 零基础学习(三十二)通过Streams和DOM方式读写XML的更多相关文章

  1. salesforce零基础学习(一百二十)快去迁移你的代码中的 Alert / Confirm 以及 Prompt吧

    本篇参考: https://developer.salesforce.com/blogs/2022/01/preparing-your-components-for-the-removal-of-al ...

  2. salesforce零基础学习(九十二)使用Ant Migration Tool 实现Metadata迁移

    我们在做项目时经常会使用changeset作为部署工具,但是某些场景使用changeset会比较难操作,比如当我们在sandbox将apex class更改名字想要部署到生产的org或者其他环境的or ...

  3. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  4. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  5. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  6. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  7. salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见

    项目中,审批操作无处不在.配置审批流时,我们有时候会用到queue,related user设置当前步骤的审批人,审批人可以一个或者多个.当审批人有多个时,邮件中获取当前记录的审批人和审批意见就不能随 ...

  8. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  9. salesforce 零基础学习(六十八)http callout test class写法

    此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...

随机推荐

  1. hadoop显示ConnectionrRefused

    产生原因重启了服务器 (1)在安装目录/root/cloud/hadoop-2.2.0/ 重新hdfs namenode -format (2) 目录/root/cloud/hadoop-2.2.0/ ...

  2. Winodow Server Backup学习向导-window 2008

    1.安装Window Server Backup 2.备份服务器 3.恢复服务器 4.优化和备份服务器性能 Windows Server Backup 中的新增功能有哪些? Windows Serve ...

  3. 关于H5本部缓存localStorage,sessionStorage

    HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前,这些都是由 coo ...

  4. 我的Sharepoint母版页的使用

    在Sharepoint 2010母版页文件夹里面,有一个叫v4.master的母版页文件. 在它的基础上修改成想要的母版页.我们用最少的修改完成我们想要的效果. 我们有时是要这样的一个母版页,顶部Ri ...

  5. Strong name signature not valid for this assembly Microsoft.mshtml.dll

    Strong name signature not valid for this assembly Microsoft.mshtml.dll  http://social.msdn.microsoft ...

  6. nginx实时记录请求状态信息( ngx_realtime_request_module)

    cd /usr/local/src/ wget "http://nginx.org/download/nginx-1.4.2.tar.gz" tar -xzvf nginx.tar ...

  7. XMPP即时通信(基础)

      使用第三方框架 XMPPFramework   #import "ViewController.h" #import "XMPPFramework.h" @ ...

  8. 【C-数组】

    一.一维数组 ①.定义方式 类型说明符 数组名 [常量表达式]; 如:int array[10]; 注意: 1) 数组的类型实际上是指数组元素的类型.对于同一个数组,其所有元素的数据类型都是相同的. ...

  9. jdbc 4.0新特性

    来自网络 在 Java SE 6 所提供的诸多新特性和改进中,值得一提的是为 Java 程序提供数据库访问机制的 JDBC 版本升级到了 4.0, 这个以 JSR-221 为代号的版本 , 提供了更加 ...

  10. Linux下安装tomcat

    安装tomcat之前首先安装jdk,这个看前面的帖子. 下面说centeros6.5安装tomcat7的方法: 1.将apache-tomcat-7.0.29.tar.gz文件上传到/home/zha ...