Search code examples
javaandroidxml-parsingxstream

Parsing xml with xstream in java (android studio)


Something is wrong and application crashes. I am trying to parse xml text into java classes, I'm using XStream library. Code crashes after I use method fromXML. My code:

XML file looks like this:

<FilesManifest>
<Group>
    <HeaderName>Pirmas hdr</HeaderName>
    <Type>theory</Type>
    <Piece>
        <FileName>11.txt</FileName>
        <HeadLine>hi1</HeadLine>
    </Piece>
    <Piece>
        <FileName>22.txt</FileName>
        <HeadLine>hi2</HeadLine>
    </Piece>
</Group>

<Group>
    <HeaderName>antras hdr</HeaderName>
    <Type>theory</Type>
    <Piece>
        <FileName>33.txt</FileName>
        <HeadLine>hi3</HeadLine>
    </Piece>
    <Piece>
        <FileName>44.txt</FileName>
        <HeadLine>hi4</HeadLine>
    </Piece>
</Group>

<Group>
    <HeaderName>tracias hdr</HeaderName>
    <Type>test</Type>
    <Piece>
        <FileName>55.txt</FileName>
        <HeadLine>hi5</HeadLine>
    </Piece>
    <Piece>
        <FileName>66.txt</FileName>
        <HeadLine>hi6</HeadLine>
    </Piece>
</Group>
</FilesManifest>

My main function code:

String fileText = ReadFile();
XStream xstream = new XStream();

xstream.alias("FilesManifest", MyFileManager.class);
xstream.alias("Group", MyGroup.class);
xstream.alias("Piece", MyPiece.class);

MyFileManager data = (MyFileManager)xstream.fromXML(fileText);

And classes for xml parsing:

public class MyFileManager {
    public List<MyGroup> getGroups() {
        return groups;
    }

    public void setGroups(List<MyGroup> groups) {
        this.groups = groups;
    }
    @XStreamImplicit(itemFieldName = "group")
    private List<MyGroup> groups = new ArrayList<MyGroup>();
}

public class MyGroup {
    private String headerName;
    private String type;

    @XStreamImplicit(itemFieldName = "piece")
    private List<MyPiece> pieces = new ArrayList<MyPiece>();

    public List<MyPiece> getPieces() {
        return pieces;
    }

    public void setPieces(List<MyPiece> pieces) {
        this.pieces = pieces;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getHeaderName() {
        return headerName;
    }

    public void setHeaderName(String headerName) {
        this.headerName = headerName;
    }

}

public class MyPiece {
    private String fileName;
    private String headLine;

    public String getHeadLine() {
        return headLine;
    }

    public void setHeadLine(String headLine) {
        this.headLine = headLine;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}

So can you advice me that code would work correctly? Maybe there is other way to parse?


Solution

  • I could make your code work by fixing 2 main issues:

    1. Your mapping is incomplete and not correct because you seem to forget that XML is case-sensitive which means that for example @XStreamImplicit(itemFieldName = "group") should be @XStreamImplicit(itemFieldName = "Group") and all the fields must be annotated with @XStreamAlias to provide an alias with the first character in capital.
    2. You did not call processAnnotations(Class type) such that your annotations are not processed.

    So at the end your code should be something like that:

    Your POJOs:

    public class MyFileManager {
        ...
        @XStreamImplicit(itemFieldName = "Group")
        private List<MyGroup> groups = new ArrayList<>();
    }
    
    public class MyGroup {
        @XStreamAlias("HeaderName")
        private String headerName;
        @XStreamAlias("Type")
        private String type;
    
        @XStreamImplicit(itemFieldName = "Piece")
        private List<MyPiece> pieces = new ArrayList<>();
    
        ...
    }
    
    public class MyPiece {
        @XStreamAlias("FileName")
        private String fileName;
        @XStreamAlias("HeadLine")
        private String headLine;
    
        ...
    }
    

    Your main function code:

    ...
    // Process the provided annotations
    xstream.processAnnotations(MyFileManager.class);
    MyFileManager data = (MyFileManager)xstream.fromXML(fileText);