XStream解析複雜XML

在項目中遇到一個需求,須要解析接口中獲取的xml文件,該xml文件以下:java

<?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看做幾個組合的類:
ui

1.  PDMDataFile > List<Part>this

2.  Part  >  Attributes |  BomUsesspa

3.  BomUses > Bom.net

而後以爲也並不複雜。因而說幹就幹,風風火火的就寫了這幾個對應的類:code

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值,這算什麼鬼?xml

<ibaAttr Type = "String" CHName = "B" ENName = "DP_Maturaty">B</ibaAttr>

給接口項目的人員聯繫了一下,肯定這個節點寫在這裏是正確的,而且有可能還有不少個。不少個?嗯,那好吧,乾脆寫到Attributes裏面,作一個List算了。因而,Attributes類也最終肯定:blog

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來解析就行了。但是在實際解析的時候,我發現,ci

<ibaAttr Type = "String" CHName = "B" ENName = "DP_Maturaty">B</ibaAttr>

IbaAttr 節點如上,沒有一個現有的方法能取到text。以前沒遇到過啊!立刻搜了一下,哈哈,有了。

http://blog.csdn.net/zhangzeyuaaa/article/details/49472671

按照如上連接講的,立馬加上自定義轉化類:

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;
}
相關文章
相關標籤/搜索