converting xml event stream into XML tree

Aleksander Slominski <[email protected]> Wed, 13 Oct 2004 10:44:20 -0500
Newsgroups gmane.text.xml.xmlpull.devel
Message-ID <[email protected]>
hi,

here is exmaple class i wrote and used for last few weeks that 
implements XmlSerializer and produces XML tree (just in case if you need 
such) thing)

alek

/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  
//------100-columns-wide------>|*/
// for more information and license info please visit 
http://storyblog.dev.java.net/

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.builder.XmlDocument;
import org.xmlpull.v1.builder.XmlElement;
import org.xmlpull.v1.builder.XmlInfosetBuilder;
import org.xmlpull.v1.builder.XmlNamespace;
import org.xmlpull.v1.builder.XmlProcessingInstruction;

/**
 * Implements XmlSerializer and produces XML tree as output - tree root 
available
 * by calling getTree().
 XML Infoset</a>)
 *
 * @version $Revision: 1.2 $ $Date: 2003/07/02 23:28:11 $ (GMT)
 * @author Aleksander Slominski [http://www.extreme.indiana.edu/~aslom]
 */

public class XmlTreeSerializer implements XmlSerializer {
   
    List stack = new ArrayList(); //JDK15 List<XmlElement>
    boolean finished;
    int counter = 1;
    XmlElement unnamed;
    XmlInfosetBuilder builder;
    private XmlElement rootElement;
   
    public XmlTreeSerializer(XmlInfosetBuilder builder) {
        this.builder = builder;
    }
   
    public XmlElement getTree() {
        if(rootElement != null) {
            return rootElement;
        } else { // return partially build tree ...
            return (XmlElement) stack.get(0);
        }
    }
   
    public void setFeature(String name, boolean state) throws 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("not supported "+name);
    }
   
    public boolean getFeature(String name) {
        return false;
    }
   
    public void setProperty(String name, Object value) throws 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("not supported "+name);
    }
   
    public Object getProperty(String name) {
        return null;
    }
   
    public void setOutput(OutputStream os, String encoding) throws 
IOException, IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("not supported - outp is XML tree");
    }
   
    public void setOutput(Writer writer) throws IOException, 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("not supported - outp is XML tree");
    }
   
    private XmlElement getStackTop() {
        if(finished) {
            throw new IllegalStateException("no more data can be 
writtend after endDocument()");
        }
        if(stack.size() == 0) {
            throw new IllegalStateException("unbalanced endElement()");
        }
        return (XmlElement) stack.get(stack.size() - 1);
    }
      
    private XmlElement getUnnamed() {
        if(unnamed == null) {
            unnamed = builder.newFragment("unnamed");
           
        }
        return unnamed;
    }
   
    private XmlElement pushElement(String namespace, String name) {
        XmlElement el;
        if(stack.size() == 0 && unnamed != null) {
            el = unnamed;
            el.setName(name);
            unnamed = null;
        } else {
            el = builder.newFragment(namespace, name);
        }
        if(stack.size() > 0) {
            getStackTop().addElement(el);
        }
        stack.add(el);
        return el;
    }
   
    private XmlElement popElement() {
       
        XmlElement el = getStackTop();
        stack.remove(stack.size() - 1);
        if(stack.size() == 0) {
            finished = true;
            rootElement = el;
        }
        return el;
    }
   
    public void startDocument(String encoding, Boolean standalone) 
throws IOException, IllegalArgumentException, IllegalStateException {
        XmlDocument doc = builder.newDocument("1.0", standalone, encoding);
    }
   
    public void endDocument() throws IOException, 
IllegalArgumentException, IllegalStateException {
        finished = true;
    }
   
    public void setPrefix(String prefix, String namespace) throws 
IOException, IllegalArgumentException, IllegalStateException {
        getUnnamed().declareNamespace(prefix, namespace);
    }
   
   
    public String getPrefix(String namespace, boolean generatePrefix) 
throws IllegalArgumentException {
        XmlElement top = getUnnamed();
        XmlNamespace n = top.lookupNamespaceByName(namespace);
        if(n == null) {
            if(!generatePrefix) {
                return null;
            }
            String generatedPrefix;
            while(true) {
                generatedPrefix = "n"+ counter++;
                if(top.lookupNamespaceByPrefix(generatedPrefix) == null) {
                    break;
                }
            }
            n = builder.newNamespace(generatedPrefix, namespace);
        }
        return n.getPrefix();
    }
   
    public int getDepth() {
        return stack.size();
    }
   
    public String getNamespace() {
        return getStackTop().getNamespaceName();
    }
   
    public String getName() {
        return getStackTop().getName();
    }
   
    public XmlSerializer startTag(String namespace, String name) throws 
IOException, IllegalArgumentException, IllegalStateException {
        unnamed = null;
        pushElement(namespace, name);
        return this;
    }
   
    public XmlSerializer attribute(String namespace, String name, String 
value)
        throws IOException, IllegalArgumentException, IllegalStateException
    {
        XmlElement top = getStackTop();
        if(namespace != null && namespace.length() > 0) {
            XmlNamespace n = top.lookupNamespaceByName(namespace);
            if(n == null) {
                getPrefix(namespace, true); //TODO combine those two methods
                n = top.lookupNamespaceByName(namespace);
                if(n == null) {
                    throw new IllegalStateException(
                        "could not find namespace declaration for 
namespace='"+namespace
                            +"' name='"+name+"' value='"+value+"'");
                }
            }
            top.addAttribute(n, name, value);
        } else {
            top.addAttribute(name, value);
        }
        return this;
    }
   
    public XmlSerializer endTag(String namespace, String name) throws 
IOException, IllegalArgumentException, IllegalStateException {
        XmlElement el = popElement();
        if(!name.equals( el.getName() ) ) {
            throw new IllegalArgumentException("end tag name "+name+" 
does not match "+el.getName());
        }
        if(! namespace.equals(el.getNamespaceName()) ) {
            throw new IllegalArgumentException("end tag namespace 
"+namespace+" does nto match "+el.getNamespaceName());
        }
        return this;
    }
   
    public XmlSerializer text(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        XmlElement top = getStackTop();
        top.addChild(text);
        return this;
    }
   
    public XmlSerializer text(char[] buf, int start, int len) throws 
IOException, IllegalArgumentException, IllegalStateException {
        text(new String(buf, start, len));
        return this;
    }
   
    public void cdsect(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        text(text);
    }
   
    public void entityRef(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("entity refs not supproted");
    }
   
    public void processingInstruction(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("processing instructions not 
supproted");
        //XmlElement top = getStackTop();
        //XmlProcessingInstruction pi = builder.newP
       
    }
   
    public void comment(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("comments not supproted");
    }
   
    public void docdecl(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        throw new IllegalStateException("docdecl not supproted");
    }
   
    public void ignorableWhitespace(String text) throws IOException, 
IllegalArgumentException, IllegalStateException {
        text(text);
    }
   
    public void flush() throws IOException {
    }
}

-- 
The best way to predict the future is to invent it - Alan Kay



------------------------ Yahoo! Groups Sponsor --------------------~--> 
$9.95 domain names from Yahoo!. Register anything.
http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/2U_rlB/TM
--------------------------------------------------------------------~-> 

 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/xmlpull-dev/

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/