Forum Stats

  • 3,734,756 Users
  • 2,247,037 Discussions
  • 7,857,481 Comments

Discussions

XMLViewer

843805
843805 Member Posts: 49,999
edited Feb 2, 2007 11:25AM in Swing
Hi all

I am trying to make an XMLViewer. Easiest way to do that I figured would be to grab an XML parser, parse the xml into a DOM Document, and convert the Document into a TreeModel.

I found a lot of code for this on the internet. First, I downloaded the latest version of Xerces, the apache XML parser. Then I scanned the web some more and found the DOMTreeWalkerTreeModel code

http://www.java2s.com/Code/Java/XML/DOMTreeWalkerTreeModel.htm

voila. I've got a treemodel.

Now, my only problem is that I want the tree to look a little different.

My XML looks like
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://www.provenir.com/schemas">
	<xsd:element name="a" type="b"/>
	<xsd:complexType name="c">
		<xsd:all>
			<xsd:element name="d" type="e" minOccurs="1" maxOccurs="1"/>
		</xsd:all>
		<xsd:attribute name="Org" type="xsd:string"/>
		<xsd:attribute name="sessionID" type="xsd:string"/>
		<xsd:attribute name="stack" type="xsd:string"/>
		<xsd:attribute name="Version" type="xsd:string" use="optional"/>
		<xsd:attribute name="ProductType" type="xsd:string" use="optional"/>
but when I install it in a JTree and view it I see branches like
[xsd:schema: null]
  [xsd:element: null]
  [xsd:complexType:null]
...
I'd like to see the actual attributes in the nodes - the name and type fields at the very least.

Anyone know how I can get the TreeWalker to display these nodes differently?

Comments

  • kirillcool
    kirillcool Member Posts: 641
    edited Feb 1, 2007 4:12PM
    Bruce Eckel's Thinking in Java (free PDF download - search on Google) has complete example of showing XML as a tree.
  • 843805
    843805 Member Posts: 49,999
    Bruce Eckel's Thinking in Java (free PDF download -
    search on Google) has complete example of showing XML
    as a tree.
    On what page?

    Also, just showing XML doesn't actually solve my problem. I've got to get it into a TreeModel somehow
  • kirillcool
    kirillcool Member Posts: 641
    Once again - this book shows a complete example of showing XML as a tree. Download the free PDF and search for JTree inside.
  • kirillcool
    kirillcool Member Posts: 641
    Damn, i was sure that it was in that book. My apologies - last time i read it ws 5 years ago. Here is the link to Sun tutorial that shows a complete example:

    http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/dom/3_tree.html
    http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/dom/work/DomEcho04.java
  • kirillcool
    kirillcool Member Posts: 641
    Also see

    http://www.phptr.com/articles/article.asp?p=26351&seqNum=3&rl=1

    And many others from googling "jtree dom xml".
  • 843805
    843805 Member Posts: 49,999
    Few things:
    1) Xerces is built-in to Java from 5.0 and up
    2) Here's a TreeNode implementation that contains a org.w3c.dom.Node
    3) There's an example of using it below the code

    ------------ TreeNode ---------------
    import java.util.*;
    import javax.swing.tree.*;
    import org.w3c.dom.*;
    
    public class XMLTreeNode implements TreeNode {
    	
    	private Node xmlNode;
    	private XMLTreeNode parent;
    	private ArrayList<XMLTreeNode> children;
    	private Boolean showAttributes;
    	
    	public XMLTreeNode(Node xmlNode) {
    		this.xmlNode = xmlNode;
    		showAttributes = Boolean.TRUE;
    	}
    	
    	protected XMLTreeNode(Node xmlNode, XMLTreeNode parent) {
    		this(xmlNode);
    		this.parent = parent;
    	}
    	
    	public boolean getShowAttributes() {
    		if (showAttributes != null) {
    			return showAttributes.booleanValue();
    		}
    		if (parent != null) {
    			return parent.getShowAttributes();
    		}
    		return false;
    	}
    	
    	public void setShowAttributes(Boolean set) {
    		showAttributes = set;
    	}
    	
    	public String getXMLTag() {
    		
    		boolean includeAttributes = getShowAttributes();
    		
    		if (xmlNode instanceof Element && includeAttributes) {
    			Element e = (Element)xmlNode;
    			StringBuilder buf = new StringBuilder();
    			
    			buf.append(e.getTagName());
    			if (e.hasAttributes()) {
    				NamedNodeMap attr = e.getAttributes();
    				int count = attr.getLength();
    				for (int i = 0; i < count; i++) {
    					Node a = attr.item(i);
    					if (i == 0) {
    						buf.append(" [");
    					}
    					else {
    						buf.append(", ");
    					}
    					buf.append(a.getNodeName()).append("=").append(a.getNodeValue());
    				}
    				buf.append(']');
    			}
    			return buf.toString();
    		}
    		else if (xmlNode instanceof Text) {
    			return xmlNode.getNodeValue();
    		}
    		
    		return xmlNode.getNodeName();
    	}
    	
    	public List<XMLTreeNode> getChildren() {
    		if (children == null) {
    			loadChildren();
    		}
    		return new ArrayList<XMLTreeNode>(children);
    	}
    
    	public Enumeration children() {
    		if (children == null) {
    			loadChildren();
    		}
    		final Iterator<XMLTreeNode> iter = children.iterator();
    	    return new Enumeration() {
    	    	public boolean hasMoreElements() { return iter.hasNext(); }
    	    	public Object nextElement() { return iter.next(); }
    	    };
        }
    
    	public boolean getAllowsChildren() {
    	    return true;
        }
    
    	public TreeNode getChildAt(int childIndex) {
    		if (children == null) {
    			loadChildren();
    		}
    		return children.get(childIndex);
        }
    
    	public int getChildCount() {
    		if (children == null) {
    			loadChildren();
    		}
    		return children.size();
        }
    
    	public int getIndex(TreeNode node) {
    		if (children == null) {
    			loadChildren();
    		}
    	    
    		int i = 0;
        	for (XMLTreeNode c : children) {
        		if (xmlNode == c.xmlNode) {
        			return i;
        		}
        		i++;
        	}
        	
    	    return -1;
        }
    
    	public TreeNode getParent() {
    	    return parent;
        }
    
    	public boolean isLeaf() {
    		if (xmlNode instanceof Element) {
    			return false;
    		}
    		if (children == null) {
    	    	loadChildren();
    	    }
    	    return children.isEmpty();
        }
    	
    	public String toString() {
    		return getXMLTag();
    	}
    	
    	protected void loadChildren() {
    		NodeList cn = xmlNode.getChildNodes();
    		int count = cn.getLength();
    		
    		children = new ArrayList<XMLTreeNode>(count);
    		for (int i = 0; i < count; i++) {
    			Node c = cn.item(i);
    			if (c instanceof Text && c.getNodeValue().trim().length() == 0) {
    				continue;
    			}
    			children.add(new XMLTreeNode(cn.item(i), this));
    		}
    	}
    }
    ------------------ Example ------------------
    import java.io.File;
    
    import javax.swing.*;
    import javax.swing.tree.DefaultTreeModel;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.DOMConfiguration;
    import org.w3c.dom.Document;
    
    public class XMLTreeModel {
    
    	public static void main(String[] args) throws Exception {
    		DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    		Document doc = db.parse(new File("test.xml"));
    		DOMConfiguration dc = doc.getDomConfig();
    		dc.setParameter("comments", Boolean.FALSE);
    		doc.normalizeDocument();
    		
    		JTree tree = new JTree(new DefaultTreeModel(new XMLTreeNode(doc)));
    		tree.setRootVisible(false);
    		tree.setShowsRootHandles(true);
    		
    		JFrame f = new JFrame("Test");
    		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		f.add(new JScrollPane(tree));
    		f.pack();
    		f.setVisible(true);
    	}
    }
  • 843805
    843805 Member Posts: 49,999
    Hi all

    Just wanted to let you know that I got this sorted out. The solution was something like yours Jaspre. What I did was I created my own TreeCellRenderer to display the information I want
This discussion has been closed.