XML Java IO Writer...

Tyler Baker tyler at infinet.com
Fri Feb 6 15:21:41 GMT 1998


A while back I brought up the idea of having an XML InputStream which
inherits FilterInputStream and did not get much response.  Anyways, it
would of been better for this to be an XMLReader since the Reader
classes handle all of the nitty gritty character conversion for you in
the first place.

Well due to the demands of the application I am writing now, it needs to
format as well as parse XML data from a variety of streams so for now I
am proposing that aside from just SAX, we have an IO package in the
org.xml domain which could possibly have parsers assigned to them.  I
spent about half a day and wrote an XMLWriter class which is an
extension of FilterInputStream for preparing XML Documents from Java
without having to do a lot of OutputStream.write() calls manually from
line to line.  Things are packaged right now under org.xml.io, but that
is only tentatively as I do not have any real permission from the guy
who owns the rights to xml.org (I can't remember who you are so maybe
this will get your attention).  Right now I am using this in my own
application and it works beautifully.  This is what I would call a 0.1
version since it does not handle all sorts of things like Notations and
lots of other stuff.

You can get the zip file with source code included.at
http://www.infinet.com/~tyler/xml/xmlio01.zip

Here is a brief description of the classes included:

package org.xml.io;

import java.io.Writer;
import java.io.FilterWriter;
import java.io.IOException;
import java.util.Hashtable;

public class XMLWriter extends FilterWriter {
  public XMLWriter(Writer out, String padding) {}

  public void writeDocument(Element rootElement, String ID) throws
IOException {}
  public void writeDocument(Element rootElement, String ID, Entity[]
entities) throws IOException {}
  public void writeDocument(Element rootElement, String ID, Entity[]
entities, boolean system) throws IOException {
  private String replaceText(String content) {}
}

This class takes as another argument, another Writer and a String which
is essentially used for padding the nested levels of your document.  For
example, you could use two spaces as padding or else just a tab.

You would create this class by making a call like this:

      XMLWriter writer = new XMLWriter(new OutputStreamWriter(out), "
");

where out is of type OutputStream.  To write a document you call
writeDocument() which takes three forms.  writeDocument(Element
rootElement, String ID) is the same as writeDocument(Element
rootElement, String ID, null, true) and writeDocument(Element
rootElement, String ID, Entity[] entities) is the same as
writeDocument(Element rootElement, String ID, Entity[] entities, true);

writeDocument(Element rootElement, String ID, Entity[] entities, boolean
system) is what is actually called.

The element type is the root element you write, ID is the system or
public ID of the DTD, entities are an array of type Entity[] which is
used to replace in the document, and system is a flag indicating whether
ID should be treated as a system ID or a public ID.  So in my code I
call this (the class calling this is of type element).

      writer.writeDocument(this, "forumReference.dtd");


package org.xml.io;

public interface Element {
  String getName();

  // may return null
  String getContent();

  // may return null
  Attribute[] getAttributes();

  // may return null
  Element[] getChildren();

  // may return null
  String getComments();
}

This interface defines an element type.  Usually you implement this for
each class which has data that can be mapped to an XML document.  If on
the other hand you have a class which should not be inherited or is even
final, then use inner classes to solve your problem.  For example, for
java.net.InetAddress I use this in my code to implement the Element[]
getChildren method.  I use AbstractElement (included on org.xml.io) so I
only have to redefine the methods that can return null anyways.

  public Element[] getChildren() {
    Element[] children = new Element[4];

    children[0] = new AbstractElement() {
      public String getName() {
        return "id";
      }
      public String getContent() {
        return ID;
      }
    };

    children[1] = new AbstractElement() {
      public String getName() {
        return "host";
      }
      public String getContent() {
        return host.getHostAddress();
      }
    };

    children[2] = new AbstractElement() {
      public String getName() {
        return "port";
      }
      public String getContent() {
        return String.valueOf(port);
      }
    };

    children[3] = new AbstractElement() {
      public String getName() {
        return "ior";
      }
      public String getContent() {
        return IOR;
      }
    };

    return children;
  }



package org.xml.io;

public interface Entity {
  String getName();
  String getValue();
}

The Entity class is basically for replacement text of course.  What it
will do is replace any occurrences of getValue() in the rest of the
stream with a '&' prepended and a ';' appended to getName().  when you
call writeDocument() every entity passed will be checked in the
document.  This is an expensive operation so use it wisely.  If null is
passed as the Entity[] argument to writeDocument, then no checks will
occur.


The XMLWriter class will recursively descent from the root element to
all sub elements and get their content and write it out.  This package
is something I spent half a day on to basically get the job done for
what I needed to do, and I would more than happily GPL it all later on
under the xml.org.io package if given permission and there is interest
in doing more (fixing bugs and adding complete XML functionality).
Right now it all works for what I am doing and chopped about 300 lines
of code (what I guess people call report writing) out of my
application.  The less code in my app, the better.  Which also makes me
ask is it better to have a parser which may be large in code size, but
is easy to use so my production code is small, or a parser with little
functionality that makes my production code large.  Of course you can
sometimes have the best of both worlds.

Tyler

Tyler


xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev at ic.ac.uk
Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/
To (un)subscribe, mailto:majordomo at ic.ac.uk the following message;
(un)subscribe xml-dev
To subscribe to the digests, mailto:majordomo at ic.ac.uk the following message;
subscribe xml-dev-digest
List coordinator, Henry Rzepa (mailto:rzepa at ic.ac.uk)




More information about the Xml-dev mailing list