ryvianstyron ryvianstyron - 1 month ago 5
Android Question

Using simple XML in android, find a way to capture order of elements?

I've been looking for a way to capture the order of element's listed within a tag, but haven't been very successful..

EDIT NEW:

<android>
<leags>
<leag name = "someName">
<headlines>
<pageType>headlines</pageType>
<story>someStoryURL</story>
<fullStory>someFullStoryURL</fullStory>
</headlines>
<scores></scores>
<statistics></statistics>
</leag>
<leags>
</android>


-Want to capture the order of elements in leag as 1)headlines 2)scores 3)statistics. If the xml changes and scores is listed before headlines it would be 1)scores 2)headlines 3)statistics.

I parse only android - Like this:

@Root(name = "android", strict = false)
public class android
{
@ElementList(name = "leags", required = false)
private List<Leag> leags;

public Leag getLeagByName(String name)
{ // go through list of leags and return leag with matching name}
}


So in my "leag" object I'd want to capture the order of elements - Is there a way to do that?

I'm assuming you'd need to set new AnnotionStrategy() like this:

tAndroid android = null;
Serializer serial = new Persister(new AnnotationStrategy());
android = serial.read(android .class, source);

League x= android.getLeagueByName("oeoe");
for(String s: x.getOrder())
{
Log.i("Order", s);
}


BEFORE EDIT:

Supposing the xml above is what's being pased by the following code:

@Element(name="headlines")
public class Headlines
{
@Element(name="pageType", required = false)
private String pageType;

@Element(name="story", required = false)
private String storiesURL;

@Element(name="fullStory", required = false)
private String fullStoryURL;

public String getStoriesURL()
{
return storiesURL;
}
public String getFullStoryURL()
{
return fullStoryURL;
}
@Override
public String toString()
{
return "PageType: " + this.pageType +
"\nStoriesURL: " + this.storiesURL +
"\nFullStoryURL: " + this.fullStoryURL;
}
}


Is there a way to somehow return the order in which the elements get parsed?

Like a method that will return a string of some sort with the correct order like:


  1. pageType

  2. story

  3. fullStory


Answer

You can use a Converter to get the order. But you can't return the order from it (or better: you can, but better don't do it).

It's relatively easy to get the order - the trick is getting it out from the Converter. On way is to add a list to your class and store it there.

Implementation:

@Root(name = "headlines")
@Convert(value = Headlines.HeadlinesConverter.class)
public class Headlines
{
    @Element(name="pageType", required = false)
    private String pageType;
    @Element(name="story", required = false)
    private String storiesURL;
    @Element(name="fullStory", required = false)
    private String fullStoryURL;

    private List<String> order; // Here we save the order of the elements


    public String getPageType()
    {
        return pageType;
    }


    public String getStoriesURL()
    {
        return storiesURL;
    }


    public String getFullStoryURL()
    {
        return fullStoryURL;
    }


    public List<String> getOrder()
    {
        return order;
    }



    @Override
    public String toString()
    {
        return "Headlines{" + "pageType=" + pageType 
                + ", storiesURL=" + storiesURL 
                + ", fullStoryURL=" + fullStoryURL + '}';
    }


    // You can implement the converter as an extra class too
    static class HeadlinesConverter implements Converter<Headlines>
    {
        @Override
        public Headlines read(InputNode node) throws Exception
        {
            Headlines h = new Headlines();
            h.order = new ArrayList<>(3);

            InputNode next = node.getNext();

            while( next != null )
            {
                final String value = next.getValue();

                /*
                 * You can use reflection (= slower) instead the switch, or
                 * remove the switch:
                 * 
                 *     h.order.add(next.getName());
                 * 
                 * and do this after the while loop:
                 * 
                 *     h.pageType = node.getNext("pageType");
                 *     ...
                 */
                switch(next.getName())
                {
                    case "pageType":
                        h.pageType = value;
                        break;
                    case "story":
                        h.storiesURL = value;
                        break;
                    case "fullStory":
                        h.fullStoryURL = value;
                        break;
                    default:
                        /* Maybe some error-handling here?! */
                        break;
                }

                h.order.add(next.getName()); // add 'value' if you want the order of the values

                next = node.getNext();
            }

            return h;
        }


        @Override
        public void write(OutputNode node, Headlines value) throws Exception
        {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}

Note: I didn't use setter here - but it's better you do so.

Example code:

final File f = new File("test.xml");

Serializer ser = new Persister(new AnnotationStrategy()); /* ! */
Headlines h = ser.read(Headlines.class, f);

int i = 1;

for( String s : h.getOrder() )
{
    System.out.println((i++) + ". " + s);
}

and finally the output:

1. pageType
2. story
3. fullStory
Comments