[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Wish list for XMLApplication Framework
Dmitri Kondratiev wrote: > The following are some of the features I'd like to be able to use in > XMLApplication Framework : > > - Support for both, event-based and tree-based parsers, to serialize XML > elements to application-specific element-objects. > Tree-based approach is certainly cleaner when you need to parse document as > a whole, but, imagine, in my appl. I may need to stop parsing relatively big > document in the middle, when I come across some element. So I don't need the > whole tree! And still I may need to instantiate my appl. specific > element-objects. > > - Runtime configuration of "element-semantic" handlers. > Ideally I'd like to be able to switch element-semantic handlers in run-time. > This might seem nonsense first, but if you give this idea a second thought > you'll see the point. XML is very wise to **not imply element semantic**, so > it may be useful for some app. (such as mine) to be able to switch one or > more times when processing a document from one set of element-objects to > another. In other words the ability to bind different semantic-handlers (and > thus element-objects) to elements in runtime is needed. Naming handler in > the XML document will allow to start parsing with some general > "semantic-switch" handler, that will activate different semantic-handlers as > needed. I already have a solution to this in a parser/formatter I have written for my application. The parser is non-validating and is very far from being something a third party could really use. But it works great (despite its lack of speed at the moment) for my application. There is an XMLReader and an XMLWriter. The parser of course is the reader and the formatter is of course the writer. These two classes are sublasses of java.io.Filter*Reader. > - Basic support for element-object to element markup serialization. This > will allow application to modify element-object in runtime and then > serialize it **in application-specific way** back in markup representation > by means of XMLDataOutputStream stream connected to XML document instance. I do this already be their being a root element (the document) and when the parser comes across a start element tag or an empty element tag, the the Element object (handler) is queried at run-time for a a sub-element or other object handler like a PI. This is the following interface I have now for Element. It should give you a good idea of what is going on. package com.dais.populous.util.xml; public interface Element { String getElementName(); // Attribute forAttributeName(String attributeName, int type, int index); void setElementAttributes(Attribute[] attributes); // may return null Attribute[] getElementAttributes(); // Returns a child element given an element name and content index Element forElementName(String elementName, int index); // Returns a processing instruction for this element given a target application // name and content index. ProcessingInstruction forProcessingInstructionTarget(String target, int index); void setElementCharacterData(String data, int index); // may return null Object[] getElementContent(); } Since this is an interface, you can have each of your objects implement this interface (or subclass an Adapter class) in your object graph and for objects that are final and cannot be sublassed like InetAddress, you can write an anonymous inner class to handle this type of object. Here is some code from my actual application. Note: the bounds object should probably utilize four attributes rather than 4 subelements, but in my DTD I happen to use this right now for completeness. All of these methods are from a class I call Capsule. A parent model class which acts as a Document and contains "Capsules" also implements Element so you can easily initialize/save objects with this method. public void format(OutputStream out) { try { XMLWriter writer = new XMLWriter(new OutputStreamWriter(out), " "); writer.writeDocument(this, "capsule.dtd"); writer.close(); } catch (IOException e) { e.printStackTrace(); } } public String getElementName() { return "capsule"; } public Object[] getElementContent() { byte[] data = getComponentData(); Object[] content = new Object[3 + ((data != null) ? 1 : 0)]; content[0] = capsuleEntry; content[1] = new BasicElement("component-name", componentName); content[2] = new BoundsElement(); if (data != null) content[3] = new BasicElement("component-data", DataUtil.encoder.encodeBuffer(data)); return content; } public void parse(InputStream in) { try { XMLReader reader = new XMLReader(new InputStreamReader(in)); reader.readDocument(this); in.close(); } catch (IOException e) { e.printStackTrace(); } } public Element forElementName(String elementName, int index) { if (elementName.equals("capsule-entry")) { capsuleEntry = new CapsuleEntry(); return capsuleEntry; } else if (elementName.equals("component-name")) { return new AbstractElement() { public String getElementName() { return "component-name"; } public void setElementCharacterData(String data, int index) { componentName = data.trim(); } }; } else if (elementName.equals("bounds")) { return new BoundsElement(); } else if (elementName.equals("component-data")) { return new AbstractElement() { public String getElementName() { return "component-data"; } public void setElementCharacterData(String data, int index) { try { setComponentData(DataUtil.decoder.decodeBuffer(data.trim())); } catch (IOException e) { e.printStackTrace(); } } }; } return null; } public void setElementAttributes(Attribute[] attributes) {} public Attribute[] getElementAttributes() {return null;} public ProcessingInstruction forProcessingInstructionTarget(String target, int index) {return null;} public void setElementCharacterData(String data, int index) {} class BoundsElement extends AbstractElement { public String getElementName() { return "bounds"; } public Object[] getElementContent() { Object[] content = new Object[4]; Rectangle bounds = getBounds(); content[0] = new BasicElement("x", String.valueOf(bounds.x)); content[1] = new BasicElement("y", String.valueOf(bounds.y)); content[2] = new BasicElement("width", String.valueOf(bounds.width)); content[3] = new BasicElement("height", String.valueOf(bounds.height)); return content; } public Element forElementName(String elementName, int index) { if (elementName.equals("x")) { return new AbstractElement() { public String getElementName() { return "x"; } public void setElementCharacterData(String data, int index) { Rectangle bounds = getBounds(); bounds.x = Integer.parseInt(data.trim()); setBounds(bounds); } }; } else if (elementName.equals("y")) { return new AbstractElement() { public String getElementName() { return "y"; } public void setElementCharacterData(String data, int index) { Rectangle bounds = getBounds(); bounds.y = Integer.parseInt(data.trim()); setBounds(bounds); } }; } else if (elementName.equals("width")) { return new AbstractElement() { public String getElementName() { return "width"; } public void setElementCharacterData(String data, int index) { Rectangle bounds = getBounds(); bounds.width = Integer.parseInt(data.trim()); setBounds(bounds); } }; } else if (elementName.equals("height")) { return new AbstractElement() { public String getElementName() { return "height"; } public void setElementCharacterData(String data, int index) { Rectangle bounds = getBounds(); bounds.height = Integer.parseInt(data.trim()); setBounds(bounds); } }; } return null; } } The nicest thing about this approach is that if there is an element the Element handler cannot handle, then null is returned and the parser simply ignores all subelements of that element. This is like ignoring all the stuff in between the Applet Tag if a browser cannot understand it. Also, since Element handlers are returned by reference, you don't need to instantiate special objects to wrap the XML data like you would if you built a tree based model of the XML data. Of course using this approach you could still easily build a big old tree if you wanted to. Regards, Tyler xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev@i... Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/ To (un)subscribe, mailto:majordomo@i... the following message; (un)subscribe xml-dev To subscribe to the digests, mailto:majordomo@i... the following message; subscribe xml-dev-digest List coordinator, Henry Rzepa (mailto:rzepa@i...)
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|