The Java Program: XML.java

  1 import java.util.StringTokenizer;
  2 import java.util.LinkedList;
  3 import java.util.Stack;
  4 import java.util.Iterator;
  5 
  6 abstract class XML {
  7    
  8    public static void main (String args []) {
  9       System.out.println (XML.parse (args[0]));
 10    }
 11 
 12 
 13    public static XML parse (final String s) {
 14       final StringTokenizer st = new StringTokenizer (s, "<>", true);
 15       final Stack stack = new Stack();
 16       final XML root = new Element ("root");
 17 
 18       stack.push (root);
 19       String expect = "<";
 20       String previous=null;
 21 
 22       while (st.hasMoreTokens()) {
 23          final Element current = (Element) stack.peek ();
 24          final String t = st.nextToken();
 25          if (t.equals("<")) {
 26             if (previous!=null) {
 27                current.add (new Text(previous));
 28             }
 29             previous=null;
 30             expect = ">";
 31          } else if (t.equals(">")) {
 32             if (current.doesClose (previous)) {
 33                stack.pop();
 34             } else if (previous.endsWith("/")) {
 35                current.add (new SelfClosing (previous));
 36             } else {
 37                final Element e = new Element (previous);
 38                current.add (e);
 39                stack.push (e);
 40             }
 41             previous=null;
 42             expect = "<";
 43          } else {
 44             previous = t;
 45          }
 46       }
 47       return (root);
 48    }
 49 
 50    public String toString () { return toString (""); }
 51    abstract String toString (String prefix);
 52 }
 53 
 54 class SelfClosing extends XML {
 55    String tag;
 56    private Object attributes; // unused
 57    SelfClosing (String t) {tag=t;}
 58    public String toString (String prefix) {return prefix+"<"+tag+">";}
 59 }
 60 
 61 class Element extends SelfClosing {
 62    LinkedList subelements = new LinkedList ();
 63    
 64    Element (String t) { super(t); }
 65 
 66    public boolean doesClose (String tag) {
 67       return (tag.equals ("/"+this.tag));
 68    }
 69 
 70    public void add (XML e) { subelements.add (e); }
 71 
 72    public String toString (String prefix) {
 73       String r = prefix + "<"+tag+">\n";
 74       String e = prefix + "</"+tag+">";
 75       for (Iterator i = subelements.listIterator(0); i.hasNext(); ) {
 76          r=r.concat (((XML) i.next()).toString (prefix+".")+"\n");
 77       }
 78       return r+e;
 79    }
 80 }
 81 
 82 class Text extends XML {
 83    String text;
 84    Text (String t) {text=t;}
 85    public String toString (String prefix) {return prefix+text;}
 86 }
 87