parsing pattern: parsing code mirrors XML structure

Aleksander Slominski <[email protected]>
Newsgroups gmane.text.xml.xmlpull.devel
Message-ID <[email protected]>
"Duffey, Kevin" wrote:

> Alrighty, I will do so, I'll try using the XMLPULL API directly. I
> didn't see the nextText() call. I take it it handles the white space
> like you said the PullWrapper does.
>
> I'll see if I can think of anything the api needs, but it probably
> doesn't. As long as it is simple. Really the PullWrapper class is very
> simple. The API does do the same thing, but requires a little bit more.
> So my only suggestion would be to look at the 4 methods in PullWrapper
> and see if you can do something similar, so that the nextText() +
> require() call is not needed. Again, it is VERY simple just saying
> parseStartTag("Tag name"). If you know the sequence it is in, this is a
> super easy approach.

hi,

that is a really nice thing about pull parsing API: you are in control to ask
parser for input and no parser calling you back whenever it decides (like SAX)

> Question for you. My XML files will have multiple nodes that are the
> same. For example:
>
> <sellers>
>         <seller>
>                 <name>1</name>
>         </seller>
>         <seller>
>                 <name>2</name>
>         </seller>
>         <seller>
>                 <name>3</name>
>         </seller>
> </sellers>
>
> So, I assume I need to do a sort of do..while(<seller>) tag exists. What
> is the way to do this to continue to loop through all nodes that are the
> same at a given level, so that each can be processed? I have to
> "combine" a number of these into one of our structures that stores as a
> single row in the database.

very good questions. i am trying to gather some xml pull parsing patterns
and put them on web page -- this one is the most prominent pattern
that i encounter "Parsing code mirrors XML structure" (see below).

as an example i am attaching complete java file that does parsing
of address book with multiple entries (similarly to sellers/seller),
and here is result (i have commented code for XmlSerializer
as this API is not yet finalized):


     java MyAddressBook
     parser implementation class is class org.xmlpull.mxp1.MXParserCachingStrings
     Parsing simple sample XML
     Addressbook as XML:
     <n1:addressbook xmlns:n1="http://tempuri.org/addressbook"><n1:person><n1:name>Joe
     Doe</n1:name><n1:address>Sesame Street</n1:address></n1:person><n1:person><n1:name>Joe Doe
     2</n1:name></n1:person><n1:person><n1:name>Foo Bar</n1:name><n1:address>Silicon
     Streee</n1:address></n1:person></n1:addressbook>



hope it helps!

alek

ps. here is preliminary description of this pattern - i welcome all comments


PATTERN: Parsing code mirrors XML structure

When parsing nested data structures it is good idea to have code written in such way to look similarly
to input XML.

It is easy to do with XML pull parsing - one can easily loop through input and delegate more difficult
parsing to another method that encapsulates required knowledge about parsing only one well determined
XML fragment.

Example:

Let consider this simple XML code that represents address book consisting of list of persons.

<addressbook xmlns="http://tempuri.org/addressbook">
  <person>
     <name>Joe Doe</name>
     <address>Sesame Street</address>
   </person>
   <person>
     <name>Joe Doe 2</name>
   </person>
</addressbook>

This XML naturally translates to two function - first we need need to get each address book entry
(readAddressBook) and then to parse each entry (readPerson). As a result of calling first function user
will get at Vector with list of entries that were in XML:

 public Vector readAddressBook(XmlPullParser pp) throws XmlPullParserException, IOException
  {
        Vector addressBook = new Vector();

State of input is represented by XML pull parser instance (passed as pp parameter to this function). We
need to move parser to first start tag, check that it has name "addressbook" and namespace
http://tempuri.org/addressbook

        pp.nextTag();
        pp.require(pp.START_TAG, SAMPLE_NS, "addressbook");

Now we need to loop through every start tag, extract person info and keep looping until "addressbook"
end tag is reached

        // read each person
        int eventType;
        // not using nextTag() guarantees that only START_TAG or END_TAG may be read
        while((eventType = pp.nextTag()) != pp.END_TAG) {
                if(eventType == pp.START_TAG) {

parsing of <person> start tag is delegated to another method - that makes code nicer to read!


                  Person person = readPerson(pp);
                  addressBook.add( person );
                }
         }
        return addressBook;
  }

Similarly readPerson will extract info from XML to create Person object (see sample MyAddressBook.java)
MyAddressBook.java (application/x-unknown-content-type-codeguide.javafile, 4.9 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.