XStream解析复杂XML

前端之家收集整理的这篇文章主要介绍了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.jb51.cc/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;
}

猜你在找的XML相关文章