简体   繁体   中英

Simple XML Framework Parser Issue - XML Parsing in Android

I'm having a problem with parsing XML in Android app, a question here implies that there are 4 types of XML parsing mechanism advised: - SAX - DOM - XmlPullParser - Simple XML Framework

While Simple Framework is amazing and I was already working with it I hit a dead end when I found out it can't support @Text and @Element in the same class, which sucks because I can't change my XML Scheme.

So ideas are appreciated and any advises will be great.

SJXP is high performance library built as a very thin layer on top of the STAX pull parsing spec (works on Android with no dependencies).

It isn't an ORM library like Simple or JAXB, it is instead focused on the maximal parsing performance given to us by the pull parsing spec but with a splash of XPath to provide easy-to-define parse rules instead of managing the pull parser's state yourself.

For example, you would target certain elements in your XML with a rule, like so (this is my an RSS parser example built with it):

IRule linkRule = new DefaultRule(Type.CHARACTER, "/rss/channel/item/link") {
    @Override
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        // 'text' is the link; store it, print it, whatever you need...
    }
}

You define any number of rules and give them to an instance of the XMLParser (which is reusable) and then just hand it InputStreams for XML to parse for you according to those rules.

The parsing overhead of SJXP ontop of the pull parser is near zero (both memory and CPU overhead) -- it literally amounts to 1-time hash code calculations then just integer comparisons to see if there is a rule match to the current position of the XML parser while it runs through the content.

It support attributes and character data -- the library even has a nice and elegant way of supporting namespaces by using []-notation... for example:

IRule channelSubjectRule = new DefaultRule(Type.CHARACTER, "/rss/channel/[http://purl.org/dc/elements/1.1/]subject") {
    @Override
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        // Got the Channel's dc:subject value! I win!
    }
}

The library wasn't meant to be another magical abstraction that hides everything from you; it is meant to be a bit lower level than that, but still higher than STAX parsing directly without introducing memory or CPU bloat to the parsing process for embedded or high-performance systems (it was written for feed parsers used in long-running spidering processes).

Well after researching for a long time I found the best XML parser suited to my needs was the JAXB Parser.

  • Supports complex types.
  • Annotation Oriented.
  • Works well with Android.
  • Very easy to understand.
  • Tools to generate JAXB annotated classes already exists in Java 1.6+

An Example to show how easy it is to use:

@XmlRootElement(name = "a")
 public class A {

@XmlElementRefs({
    @XmlElementRef(name = "lang", namespace = "http://www.w3.org/namespace/", type = Lang.class, required = false),
    @XmlElementRef(name = "subst", namespace = "http://www.w3.org/namespace/", type = Subst.class, required = false),
    @XmlElementRef(name = "include", namespace = "http://www.w3.org/namespace/", type = Include.class, required = false),
    @XmlElementRef(name = "br", namespace = "http://www.w3.org/namespace/", type = Br.class, required = false),
    @XmlElementRef(name = "kw", namespace = "http://www.w3.org/namespace/", type = Kw.class, required = false),
    @XmlElementRef(name = "help", namespace = "http://www.w3.org/namespace/", type = Help.class, required = false)
})
@XmlMixed
protected List<Object> content;
@XmlAttribute(name = "cost")
protected String cost;
@XmlAttribute(name = "href", required = true)
protected String href;
@XmlAttribute(name = "key")
protected String key;

So that was the best I came up with.


Any additions are welcome :)

如果您想将xml映射到对象http://code.google.com/p/xstream-for-android/,xstream非常简单

You can use Konsume-XML : it's based on Stax/pull but it's higher level and easier to use. It doesn't map stuff to objects by default but it can be easily used to do so. Please see more examples at the Konsume-XML page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM