JDOM XMLOutputter Textclass

Hi,

I have written a simple JTree Outputter class but I don't know why (Text) o).getTextTrim(); returns nothing:

/*

* Created on 18.09.2006

*/

package xml_editor;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

import org.jdom.Attribute;

import org.jdom.CDATA;

import org.jdom.Comment;

import org.jdom.Document;

import org.jdom.Element;

import org.jdom.EntityRef;

import org.jdom.ProcessingInstruction;

import org.jdom.Text;

publicclass XMLTreeOutputter{

public HashMap<Integer, String> map;

public XMLTreeOutputter(Document doc, DefaultMutableTreeNode root)

{

addChildren(root, doc.getRootElement());

}

privatevoid addChildren(DefaultMutableTreeNode parent, Object o)

{

if(oinstanceof Element)

{

Element element = (Element) o;

String node ="Element: " + element.getName();

Iterator attrl = element.getAttributes().iterator();

while(attrl.hasNext())

{

Attribute attr = (Attribute) attrl.next();

node +=" ["+attr.getName()+"='"+attr.getValue()+"'";

}

node +="]";

DefaultMutableTreeNode newelement =new DefaultMutableTreeNode(node);

List children = element.getContent();

Iterator iterator = children.iterator();

while (iterator.hasNext())

{

Object child = iterator.next();

addChildren(newelement, child);

}

parent.add(newelement);

}

elseif (oinstanceof Document)

{

Document doc = (Document) o;

List children = doc.getContent();

Iterator iterator = children.iterator();

while (iterator.hasNext()){

Object child = iterator.next();

addChildren(parent, child);

}

}

elseif (oinstanceof Comment)

{

Comment comment = (Comment) o;

DefaultMutableTreeNode newcomment =new DefaultMutableTreeNode(comment.getText());

parent.add(newcomment);

}

elseif (oinstanceof CDATA)

{

DefaultMutableTreeNode newCDATA =new DefaultMutableTreeNode(((CDATA) o).getTextTrim());

parent.add(newCDATA);

}

elseif (oinstanceof Text)

{

Integer hash =new Integer(parent.hashCode());

System.out.println(hash);

System.out.println(((Text) o).getTextTrim());

map.put(hash, ((Text) o).getTextTrim());

System.out.println("Text");

}

elseif (oinstanceof EntityRef)

{

DefaultMutableTreeNode newEntityRef =new DefaultMutableTreeNode(((EntityRef) o).toString());

parent.add(newEntityRef);

}

elseif (oinstanceof ProcessingInstruction)

{

DefaultMutableTreeNode newPI =new DefaultMutableTreeNode(((ProcessingInstruction) o).toString());

parent.add(newPI);

}

else

{// This really shouldn't happen

System.out.println("Unexpected type: " + o.getClass());

}

}

}

I wanted to write a TreeModel for JTree, but it seems to be impossible (at least to me) to get an output like the above one (like Element: elementname [attributname='attributvalue']. But well, what's wrong with my code above? I want to fill a hashmap, so that I can show textnode contents in the right panel of a JSplitPane.

greetings,

Johannes

[6029 byte] By [Johannesa] at [2007-10-3 5:14:16]
# 1
As the documentation for the method specifically says:"If only whitespace exists, the empty string is returned."
DrClapa at 2007-7-14 23:20:47 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

My sample XML-file:

<?xml version="1.0" ?>

<!DOCTYPE perennials SYSTEM

"http://archive.corewebprogramming.com/dtds/perennials.dtd">

<perennials>

<daylily status="in-stock">

<cultivar>Luxury Lace</cultivar>

<award>

<name>Stout Medal</name>

<year>1965</year>

</award>

<award>

<name note="small-flowered">Annie T. Giles</name>

<year>1965</year>

</award>

<award>

<name>Lenington All-American</name>

<year>1970</year>

</award>

<bloom code="M">Midseason</bloom>

<cost discount="3" currency="US">11.75</cost>

</daylily>

<daylily status="in-stock">

<cultivar>Green Flutter</cultivar>

<award>

<name>Stout Medal</name>

<year>1976</year>

</award>

<award>

<name note="small-flowered">Annie T. Giles</name>

<year>1970</year>

</award>

<bloom code="M">Midseason</bloom>

<cost discount="3+" currency="US">7.50</cost>

</daylily>

<daylily status="sold-out">

<cultivar>My Belle</cultivar>

<award>

<name>Stout Medal</name>

<year>1984</year>

</award>

<bloom code="E">Early</bloom>

<cost currency="US">12.00</cost>

</daylily>

<daylily status="in-stock">

<cultivar>Stella De Oro</cultivar>

<award>

<name>Stout Medal</name>

<year>1985</year>

</award>

<award>

<name note="miniature">Donn Fishcer Memorial Cup</name>

<year>1979</year>

</award>

<bloom code="E-L">Early to Late</bloom>

<cost discount="10+" currency="US">5.00</cost>

</daylily>

<daylily status="limited">

<cultivar>Brocaded Gown</cultivar>

<award>

<name>Stout Medal</name>

<year>1989</year>

</award>

<bloom code="E">Early</bloom>

<cost currency="US" discount="3+">14.50</cost>

</daylily>

</perennials>

I changed it to

else if (o instanceof Text)

{

Integer hash = new Integer(parent.hashCode());

String character = ((Text) o).getTextTrim();

if(character != "")

map.put(hash, character);

}

but still I get a java.lang.NullPointerException :-/

Johannesa at 2007-7-14 23:20:47 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

> but still I get a java.lang.NullPointerException :-/

Well, this is new information. But not very useful information, to somebody (like all of us reading this) who doesn't know what line of code threw the exception.

By the way, that's not how you check that a string is (or isn't) empty. The == and != operators check for object equality, not equality of contents. Try this instead:if(!character.equals(""))

Also by the way, you have a lot of text nodes that contain only whitespace in that XML, so expect this code to be executed frequently.

DrClapa at 2007-7-14 23:20:47 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

ah, thanks, that should work (I get all the textvalues without whitespaces) (so for example with my file:

Luxury Lace

Stout Medal

1965

...

but I still get the NullPointerException from "map.put(hash, character);". It should simply store unique keys via Integer "hash = new Integer(parent.hashCode());" and assign the character values.

then I want to get the selected node within my GUI class, and check if it has the same value and if it has, the place the value from the textnode in the right panel:

tree.getSelectionModel().addTreeSelectionListener(

new TreeSelectionListener()

{

public void valueChanged(TreeSelectionEvent e)

{

DefaultMutableTreeNode selected =

(DefaultMutableTreeNode) e.getNewLeadSelectionPath().getLastPathComponent();

// if it's an element

if(selected.toString().substring(0,6).equals("Element"))

{

// get the hashCode from the selected node

Integer hash = new Integer(selected.hashCode());

// find the relevant text

String chartext = map.get(hash);

// display the text

TextArea.setEditable(true);

TextArea.setText(chartext);

}

}

}

);

My new XML Outputter code:

/*

* Created on 18.09.2006

*/

package xml_editor;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

import org.jdom.*;

public class XMLTreeOutputter

{

public HashMap<Integer, String> map;

public XMLTreeOutputter(Document doc, DefaultMutableTreeNode root)

{

addChildren(root, doc);

}

private void addChildren(DefaultMutableTreeNode parent, Object o)

{

if(o instanceof Element)

{

Element element = (Element) o;

String node = "Element: " + element.getName();

Iterator attrl = element.getAttributes().iterator();

if(! ((List) element.getAttributes()).isEmpty())

node +=" [";

while(attrl.hasNext())

{

Attribute attr = (Attribute) attrl.next();

node += attr.getName()+"='"+attr.getValue()+"'";

}

if(! ((List) element.getAttributes()).isEmpty())

node += "]";

DefaultMutableTreeNode newelement = new DefaultMutableTreeNode(node);

List children = element.getContent();

Iterator iterator = children.iterator();

while (iterator.hasNext())

{

Object child = iterator.next();

addChildren(newelement, child);

}

parent.add(newelement);

}

else if(o instanceof Document)

{

Document doc = (Document) o;

List children = doc.getContent();

Iterator iterator = children.iterator();

while (iterator.hasNext()) {

Object child = iterator.next();

addChildren(parent, child);

}

}

else if(o instanceof DocType)

{

DefaultMutableTreeNode newdoctype =

new DefaultMutableTreeNode("DocType: "+((DocType) o).getElementName()

+" "+((DocType) o).getSystemID()+" "+((DocType) o).getInternalSubset());

parent.add(newdoctype);

}

else if(o instanceof Comment)

{

DefaultMutableTreeNode newcomment =

new DefaultMutableTreeNode("Comment: "+((Comment) o).getText());

parent.add(newcomment);

}

else if(o instanceof CDATA)

{

DefaultMutableTreeNode newCDATA =

new DefaultMutableTreeNode("CDATA: "+((CDATA) o).getTextTrim());

parent.add(newCDATA);

}

else if(o instanceof Text)

{

Integer hash = new Integer(parent.hashCode());

String character = ((Text) o).getTextTrim();

if(! character.equals(""))

{

System.out.println(character);

map.put(hash, character);

}

}

else if(o instanceof Namespace)

{

Namespace nspace = (Namespace) o;

String prefix = nspace.getPrefix();

if(prefix != null)

{

prefix = "[None]";

}

DefaultMutableTreeNode newNamespace =

new DefaultMutableTreeNode(

"Namespace: prefix='"+prefix+"' IRI='"

+nspace.getURI()+"'");

parent.add(newNamespace);

}

else if(o instanceof EntityRef)

{

DefaultMutableTreeNode newEntityRef =

new DefaultMutableTreeNode("EntityRef: "+((EntityRef) o).toString());

parent.add(newEntityRef);

}

else if(o instanceof ProcessingInstruction)

{

DefaultMutableTreeNode newPI =

new DefaultMutableTreeNode("PI: "+((ProcessingInstruction) o).toString());

parent.add(newPI);

}

else

{ // This really shouldn't happen

System.out.println("Unexpected type: " + o.getClass());

}

}

}

Ok, that was really stupid, I didn't initialize my HashMap.

Johannesa at 2007-7-14 23:20:47 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...