XStream解析复杂XML
2015-12-08 14:18
513 查看
在项目中遇到一个需求,需要解析接口中获取的xml文件,该xml文件如下:
拿到这个xml文件大概分析了一下,完全可以把这个xml看作几个组合的类:
1. PDMDataFile > List<Part>
2. Part > Attributes | BomUses
3. BomUses > Bom
然后觉得也并不复杂。于是说干就干,风风火火的就写了这几个对应的类:
可是写到Attributes的时候,我犯傻了,这个类该怎么写呢?Attributes上面都是属性,还好说,它最下面这个ibaAttr,又包含属性,又包含text值,这算什么鬼?
给接口项目的人员联系了一下,确定这个节点写在这里是正确的,并且有可能还有很多个。很多个?嗯,那好吧,干脆写到Attributes里面,做一个List算了。于是,Attributes类也最终确定:
既然 IbaAttr 既有 属性,又有text,那我干脆给你添加一个text字段好了,免得到时候我没地方存text。
到这里面,按照我之前做过的方式,直接用XStream来解析就好了。可是在实际解析的时候,我发现,
IbaAttr 节点如上,没有一个现有的方法能取到text。之前没遇到过啊!马上搜了一下,哈哈,有了。
/detail/2657026761.html
按照如上链接讲的,立马加上自定义转化类:
就是这么简单,好了,整个解析就基本上完成了。如下是xstream解析对应代码:
<?xml version='1.0' encoding='UTF-8' ?> <PDMDataFile forceSend = "N" containerName = "Test_PRC1"> <Part PartID = "VCI_20150714_001" Version = "---" Revision = "" ParentUUID = ""> <Attributes> <PartName></PartName> <PartType>装配</PartType> <PartDesc></PartDesc> <PartUuid>5D0000077B</PartUuid> <CreatedBy></CreatedBy> <UpdatedBy>DES01</UpdatedBy> <Effectivity>1-5</Effectivity> <CreatedTime>2015-07-14 17:03:25</CreatedTime> <LastUpdated>2015-07-22 09:42:07</LastUpdated> <lifecycleState>UnderReview</lifecycleState> <ibaAttr Type = "String" CHName = "A" ENName = "DP_Maturaty">A</ibaAttr> </Attributes> <BomUses/> </Part> <Part PartID = "VCI_20150714_002" Version = "---" Revision = "6" ParentUUID = ""> <Attributes> <PartName></PartName> <PartType>线路图</PartType> <PartDesc></PartDesc> <PartUuid>9C00000785</PartUuid> <CreatedBy></CreatedBy> <UpdatedBy>EV5ADM</UpdatedBy> <Effectivity>1-5</Effectivity> <CreatedTime>2015-07-14 18:21:16</CreatedTime> <LastUpdated>2015-07-14 18:21:17</LastUpdated> <lifecycleState>In Work</lifecycleState> <ibaAttr Type = "String" CHName = "B" ENName = "DP_Maturaty">B</ibaAttr> </Attributes> <BomUses> <Bom PartID = "VCI_20150609_003" PartUUID = "7300000788"/> </BomUses> </Part> </PDMDataFile>
拿到这个xml文件大概分析了一下,完全可以把这个xml看作几个组合的类:
1. PDMDataFile > List<Part>
2. Part > Attributes | BomUses
3. BomUses > Bom
然后觉得也并不复杂。于是说干就干,风风火火的就写了这几个对应的类:
public class PDMDataFile { private List<Part> lstPart; public void setLstPart(List<Part> lstPart) { this.lstPart = lstPart; } public List<Part> getLstPart() { return lstPart; } }
public class Part { public String partId; public String version; public String parentUuid; private Attributes atts; private BomUses bomUses; private List<Part> subPart; // 考虑子集合 //......... 省略get set }
public class BomUses { private List<Bom> lstBom; public void setLstBom(List<Bom> lstBom) { this.lstBom = lstBom; } public List<Bom> getLstBom() { return lstBom; } }
public class Bom { private String partId; private String partUuid; public void setPartId(String partId) { this.partId = partId; } public String getPartId() { return partId; } public void setPartUuid(String partUuid) { this.partUuid = partUuid; } public String getPartUuid() { return partUuid; } }
可是写到Attributes的时候,我犯傻了,这个类该怎么写呢?Attributes上面都是属性,还好说,它最下面这个ibaAttr,又包含属性,又包含text值,这算什么鬼?
<ibaAttr Type = "String" CHName = "B" ENName = "DP_Maturaty">B</ibaAttr>
给接口项目的人员联系了一下,确定这个节点写在这里是正确的,并且有可能还有很多个。很多个?嗯,那好吧,干脆写到Attributes里面,做一个List算了。于是,Attributes类也最终确定:
public class Attributes { private String partName; private String partDesc; private String partType; private String partUuid; private String updatedBy; private String effectivity; private String lifeCycleState; private String dpMaturat; private String createdBy; private String createdTime; private String lastUpdated; private List<IbaAttr> lstIbaAttr; // 省略get set }
public class IbaAttr { private String type; private String chname; private String enname; private String text; // 省略get set }
既然 IbaAttr 既有 属性,又有text,那我干脆给你添加一个text字段好了,免得到时候我没地方存text。
到这里面,按照我之前做过的方式,直接用XStream来解析就好了。可是在实际解析的时候,我发现,
<ibaAttr Type = "String" CHName = "B" ENName = "DP_Maturaty">B</ibaAttr>
IbaAttr 节点如上,没有一个现有的方法能取到text。之前没遇到过啊!马上搜了一下,哈哈,有了。
/detail/2657026761.html
按照如上链接讲的,立马加上自定义转化类:
public class FieldDtoConvertor implements Converter { public boolean canConvert(@SuppressWarnings("rawtypes") final Class clazz) { return clazz.equals(IbaAttr.class); } public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { final IbaAttr fieldDto = (IbaAttr) value; writer.addAttribute(fieldDto.getText(), fieldDto.getText()); } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { IbaAttr result = new IbaAttr(); result.setChname(reader.getAttribute("CHName")); result.setEnname(reader.getAttribute("ENName")); result.setType(reader.getAttribute("Type")); result.setText(reader.getValue()); return result; } }
就是这么简单,好了,整个解析就基本上完成了。如下是xstream解析对应代码:
public PDMDataFile deserializeFromXML(String filePath) { XStream xstream = new XStream(new DomDriver()); xstream.registerConverter(new FieldDtoConvertor()); xstream.alias("PDMDataFile", PDMDataFile.class); xstream.addImplicitCollection(PDMDataFile.class, "lstPart"); xstream.alias("Part", Part.class); xstream.aliasAttribute(Part.class, "partId", "PartID"); xstream.aliasAttribute(Part.class, "version", "Version"); xstream.aliasAttribute(Part.class, "parentUuid", "ParentUUID"); xstream.aliasField("Attributes", Part.class, "atts"); xstream.aliasField("BomUses", Part.class, "bomUses"); xstream.alias("Attributes", Attributes.class); xstream.aliasField("PartName", Attributes.class, "partName"); xstream.aliasField("PartType", Attributes.class, "partType"); xstream.aliasField("PartDesc", Attributes.class, "partDesc"); xstream.aliasField("PartUuid", Attributes.class, "partUuid"); xstream.aliasField("UpdatedBy", Attributes.class, "updatedBy"); xstream.aliasField("Effectivity", Attributes.class, "effectivity"); xstream.aliasField("lifecycleState", Attributes.class, "lifeCycleState"); xstream.aliasField("CreatedBy", Attributes.class, "createdBy"); xstream.aliasField("CreatedTime", Attributes.class, "createdTime"); xstream.aliasField("LastUpdated", Attributes.class, "lastUpdated"); xstream.addImplicitCollection(Attributes.class, "lstIbaAttr"); xstream.alias("ibaAttr", IbaAttr.class); xstream.aliasAttribute(IbaAttr.class, "type", "Type"); xstream.aliasAttribute(IbaAttr.class, "chname", "CHName"); xstream.aliasAttribute(IbaAttr.class, "enname", "ENName"); xstream.alias("BomUses", BomUses.class); xstream.addImplicitCollection(BomUses.class, "lstBom"); xstream.alias("Bom", Bom.class); xstream.useAttributeFor("partId", Bom.class); xstream.useAttributeFor("partUuid", Bom.class); xstream.aliasAttribute(Bom.class, "partId", "PartID"); xstream.aliasAttribute(Bom.class, "partUuid", "PartUUID"); PDMDataFile result = new PDMDataFile(); try { FileInputStream fis = new FileInputStream(filePath); result = (PDMDataFile) xstream.fromXML(fis); } catch (Exception ex) { ex.printStackTrace(); return null; } return result; }
相关文章推荐
- XML 与 JSON 优劣对比
- 把网站链接卖一个好价钱: Text Link Ads 注册网赚攻略
- As3.0 xml + Loader应用代码
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- ext读取两种结构的xml的代码
- DOM2非标准但却支持很好的几个属性小结
- Ruby简洁学习笔记(二):类继承、属性、类变量
- Delphi控件ListView的属性及使用方法详解
- C#实现获取不同对象中名称相同属性的方法
- 批处理实现一行内容分行输出
- C#针对xml基本操作及保存配置文件应用实例
- Ruby程序中创建和解析XML文件的方法
- asp下查询xml的实现代码
- sqlserver FOR XML PATH 语句的应用
- 使用sp_xml_preparedocument处理XML文档的方法
- MSSQL数据库获取TEXT字段的内容长度
- EBS xml publisher中文乱码问题及解决办法
- PowerShell中Get-Date对象的常用属性和方法介绍
- Windows Powershell属性:描述对象是什么