XStream解析复杂XML
在项目中遇到一个需求,需要解析接口中获取的xml文件,该xml文件如下: <?xmlversion='1.0'encoding='UTF-8'?> <PDMDataFileforceSend="N"containerName="Test_PRC1"> <PartPartID="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-1417:03:25</CreatedTime> <LastUpdated>2015-07-2209:42:07</LastUpdated> <lifecycleState>UnderReview</lifecycleState> <ibaAttrType="String"CHName="A"ENName="DP_Maturaty">A</ibaAttr> </Attributes> <BomUses/> </Part> <PartPartID="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-1418:21:16</CreatedTime> <LastUpdated>2015-07-1418:21:17</LastUpdated> <lifecycleState>InWork</lifecycleState> <ibaAttrType="String"CHName="B"ENName="DP_Maturaty">B</ibaAttr> </Attributes> <BomUses> <BomPartID="VCI_20150609_003"PartUUID="7300000788"/> </BomUses> </Part> </PDMDataFile> 拿到这个xml文件大概分析了一下,完全可以把这个xml看作几个组合的类: 1. PDMDataFile > List<Part> 2. Part > Attributes | BomUses 3. BomUses > Bom 然后觉得也并不复杂。于是说干就干,风风火火的就写了这几个对应的类: publicclassPDMDataFile{ privateList<Part>lstPart; publicvoidsetLstPart(List<Part>lstPart){ this.lstPart=lstPart; } publicList<Part>getLstPart(){ returnlstPart; } } publicclassPart{ publicStringpartId; publicStringversion; publicStringparentUuid; privateAttributesatts; privateBomUsesbomUses; privateList<Part>subPart;//考虑子集合 //.........省略getset } publicclassBomUses{ privateList<Bom>lstBom; publicvoidsetLstBom(List<Bom>lstBom){ this.lstBom=lstBom; } publicList<Bom>getLstBom(){ returnlstBom; } } publicclassBom{ privateStringpartId; privateStringpartUuid; publicvoidsetPartId(StringpartId){ this.partId=partId; } publicStringgetPartId(){ returnpartId; } publicvoidsetPartUuid(StringpartUuid){ this.partUuid=partUuid; } publicStringgetPartUuid(){ returnpartUuid; } } 可是写到Attributes的时候,我犯傻了,这个类该怎么写呢?Attributes上面都是属性,还好说,它最下面这个ibaAttr,又包含属性,又包含text值,这算什么鬼? <ibaAttrType="String"CHName="B"ENName="DP_Maturaty">B</ibaAttr> 给接口项目的人员联系了一下,确定这个节点写在这里是正确的,并且有可能还有很多个。很多个?嗯,那好吧,干脆写到Attributes里面,做一个List算了。于是,Attributes类也最终确定: publicclassAttributes{ privateStringpartName; privateStringpartDesc; privateStringpartType; privateStringpartUuid; privateStringupdatedBy; privateStringeffectivity; privateStringlifeCycleState; privateStringdpMaturat; privateStringcreatedBy; privateStringcreatedTime; privateStringlastUpdated; privateList<IbaAttr>lstIbaAttr; //省略getset } publicclassIbaAttr{ privateStringtype; privateStringchname; privateStringenname; privateStringtext; //省略getset } 既然 IbaAttr 既有 属性,又有text,那我干脆给你添加一个text字段好了,免得到时候我没地方存text。 到这里面,按照我之前做过的方式,直接用XStream来解析就好了。可是在实际解析的时候,我发现, <ibaAttrType="String"CHName="B"ENName="DP_Maturaty">B</ibaAttr> IbaAttr 节点如上,没有一个现有的方法能取到text。之前没遇到过啊!马上搜了一下,哈哈,有了。 http://www.52php.cn/article/p-xylzfvcs-mk.html 按照如上链接讲的,立马加上自定义转化类: publicclassFieldDtoConvertorimplementsConverter{ publicbooleancanConvert(@SuppressWarnings("rawtypes")finalClassclazz){ returnclazz.equals(IbaAttr.class); } publicvoidmarshal(Objectvalue,HierarchicalStreamWriterwriter,MarshallingContextcontext){ finalIbaAttrfieldDto=(IbaAttr)value; writer.addAttribute(fieldDto.getText(),fieldDto.getText()); } publicObjectunmarshal(HierarchicalStreamReaderreader,UnmarshallingContextcontext){ IbaAttrresult=newIbaAttr(); result.setChname(reader.getAttribute("CHName")); result.setEnname(reader.getAttribute("ENName")); result.setType(reader.getAttribute("Type")); result.setText(reader.getValue()); returnresult; } } 就是这么简单,好了,整个解析就基本上完成了。如下是xstream解析对应代码: publicPDMDataFiledeserializeFromXML(StringfilePath){ XStreamxstream=newXStream(newDomDriver()); xstream.registerConverter(newFieldDtoConvertor()); 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","bomUses"); xstream.alias("Attributes",Attributes.class); xstream.aliasField("PartName",Attributes.class,"partName"); xstream.aliasField("PartType","partType"); xstream.aliasField("PartDesc","partDesc"); xstream.aliasField("PartUuid","partUuid"); xstream.aliasField("UpdatedBy","updatedBy"); xstream.aliasField("Effectivity","effectivity"); xstream.aliasField("lifecycleState","lifeCycleState"); xstream.aliasField("CreatedBy","createdBy"); xstream.aliasField("CreatedTime","createdTime"); xstream.aliasField("LastUpdated","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"); xstream.aliasAttribute(Bom.class,"partUuid","PartUUID"); PDMDataFileresult=newPDMDataFile(); try{ FileInputStreamfis=newFileInputStream(filePath); result=(PDMDataFile)xstream.fromXML(fis); }catch(Exceptionex){ ex.printStackTrace(); returnnull; } returnresult; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |