Search code examples
xmlgwtgridgxt

Displaying more complex XML in a GXT Grid using XmlReader


I have an XML response that I'd like to bind and display to a GXT grid.

The basic example I've found online says to do the following:

    // defines the xml structure
    ModelType type = new ModelType();
    type.setRoot("records");
    type.setRecordName("record");
    type.addField("Sender", "Name");
    type.addField("Email");
    type.addField("Phone");
    type.addField("State");
    type.addField("Zip");

    // use a http proxy to get the data
    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
        GWT.getHostPageBaseURL() + "data/data.xml");
    HttpProxy<String> proxy = new HttpProxy<String>(builder);

    // need a loader, proxy, and reader
    XmlLoadResultReader<ListLoadResult<ModelData>> reader = new XmlLoadResultReader<ListLoadResult<ModelData>>(
        type);

    final BaseListLoader<ListLoadResult<ModelData>> loader = new BaseListLoader<ListLoadResult<ModelData>>(
        proxy, reader);

    ListStore<ModelData> store = new ListStore<ModelData>(loader);

This works just fine if your XML is in a simple structure (ie no nested elements).

However, my XML is more like this:

<myRoot>
  <myElement>
     <first>
       <time></time>
       <place></place>
     </first>
     <second>
       <time></time>
       <place></place>
     </second>
     <third>
       <time></time>
       <place></place>
     </third>
  </myElement>
  ...
</myRoot>

How can I represent this using ModelType in order for the Grid to properly display the results?


Solution

  • Abstract

    The key is how you parse the XML document to build the ModelData (extended here as ModelType).

    GXT showcase shows how to parse their example XML into beans, and you can use your favored XML parser to do the same.

    here is a snippet from their repositories, edited based on your XML data to demonstrate how it's done:

    Code Example

    Service Implementation (with parser)

    public void parseXmlData() {
    
        try {
    
            // init parser / builder
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(getClass().getResourceAsStream("data.xml"));
            doc.getDocumentElement().normalize();
    
            // get first level
            NodeList myElementNodeList = doc.getElementsByTagName("myElement");
    
            // traverse first level
            for (int s = 0; s < myElementNodeList.getLength(); s++) {
    
                Node fstNode = myElementNodeList.item(s);
                if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
    
                    Element fstElmnt = (Element) fstNode;
                    NodeList myElementChildren = fstElmnt.getChildNodes();
    
                    // traverse second level
                    for (int c = 0; c < myElementChildren.getLength(); c++) {
    
                        Node cNode = myElementChildren.item(s);
                        if (cNode.getNodeType() == Node.ELEMENT_NODE) {
    
                            Element cElmnt = (Element) cNode;
                            NodeList timeList = cElmnt.getElementsByTagName("time");
                            NodeList placeList = cElmnt.getElementsByTagName("place");
    
                            // init beans
                            ModelType t = new ModelType();
                            // (scroll down to see how getValue() is implemented)
                            t.setTime(getValue(timeList, 0));
                            t.setPlace(getValue(placeList, 0));
    
                            // add to list
                            posts.add(t);
    
                        }
                    }
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private String getValue(NodeList fields, int index) {
        NodeList list = fields.item(index).getChildNodes();
        if (list.getLength() > 0) {
            return list.item(0).getNodeValue();
        } else {
            return "";
        }
    }
    

    you can, of course, extend this technique further (continue traversing deeper as you like) in order to match your needs.