您的位置:首页 > 其它

XStream解析复杂XML

2015-12-08 14:18 513 查看
在项目中遇到一个需求,需要解析接口中获取的xml文件,该xml文件如下:
<?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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XStream XML 属性 内容 text