1

I have a xml file:

<Generic_Name>
<Name>
<All>Home</All>
<link>value1</link>
</Name>
<Name>
<All> Filter</All>
<link>value2</link>
</Name>
</Generic_Name>

I need to get the value of <All> tags in a combo box.When the user select the combo box value (that is the value of <All>)its corresponding <link> value need to be printed in the console. I am getting the values of All to the combo box but I cannot get <link> values printed

 DocumentBuilderFactory domFactory = DocumentBuilderFactory
                    .newInstance();
    domFactory.setNamespaceAware(true);
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse("generic.xml");
    XPath xpath = XPathFactory.newInstance().newXPath();
    // XPath Query for showing all nodes value
    XPathExpression expr = xpath.compile("//Name/*/text()");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    final DefaultComboBoxModel assignGp = new DefaultComboBoxModel();
    // for (int i = 0; i < nodes.getLength(); i+)
    int i = 0;
    while (i < nodes.getLength()) {
        assignGp.addElement(nodes.item(i).getNodeValue());
        i = i + 2;
        }
    final JComboBox assignCombo = new JComboBox(assignGp);
    assignCombo.setSelectedIndex(0);
    assignCombo.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String selct=assignCombo.getSelectedItem().toString();
        // assignGp.getSelectedItem(nodes.item(i).getNextSibling());
        }
        });
    assignCombo.setBounds(150, 180, 140, 25);
    panel.add(assignCombo);
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
sangeeta
  • 80
  • 1
  • 2
  • 12
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). 2) Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Sep 18 '14 at 10:51

2 Answers2

2

(Same recommendation as Oliver Watkins (+1), using a JAXB approach)

You're making it difficult for yourself, doing it this way. You should just map your xml to java object. Say have Name class with all and link fields. I'm not great with dom and xpath, but if you are then just traverse the entire xml and map each set to a Name object and add all those Name objects to the DefaultListModel. Override the toString() of the Name class to just return the all field, that way, only the all field is rendered in the JComboBox

A much easier way that using dom/xpath, is to use JAXB which will do the binding for your, with annotations.

Tested Example:

Root Element class

@XmlRootElement(name = "Generic_Name")
public class GenericName {

    @XmlElement(name = "Name")
    protected List<Name> name;

    public List<Name> getNames() {
        if (name == null) {
            name = new ArrayList<Name>();
        }
        return this.name;
    }
}

Name class

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Name", propOrder = {
    "all",
    "link"
})
public class Name {

    @XmlElement(name = "All", required = true)
    protected String all;
    @XmlElement(required = true)
    protected String link;

    // getters and setters

    @Override
    public String toString() {
        return all;
    }
}

Result: Using Unmarshaller to unmarshal the xml. Passing the top level element type GenericName.class, when the xml is unmarshalled, a GenericName instance will be created, with the list of Names

import java.awt.event.*;
import java.io.File;
import java.util.List;
import javax.swing.*;
import javax.xml.bind.*;

public class TestComboJaxB {

    private static final String FILE_PATH = "src/combobox/genericname.xml";

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                File file = new File(FILE_PATH);
                ComboBoxModel model = new DefaultComboBoxModel(getNames(file).toArray());
                final JComboBox cbox = new JComboBox(model);
                cbox.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e) {
                        Name name = (Name)cbox.getSelectedItem();
                        System.out.println(name.getLink());
                    }
                });
                JOptionPane.showMessageDialog(null, cbox);
            }
        });
    }

    private static List<Name> getNames(File file) {
        List<Name> names = null;
        try {
            JAXBContext context = JAXBContext.newInstance(GenericName.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            GenericName genericName = (GenericName)unmarshaller
                    .unmarshal(file);
            names = genericName.getNames();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return names;
    }
}

Xml file used

<?xml version="1.0" encoding="UTF-8"?>
<Generic_Name>
    <Name>
        <All>Home</All>
        <link>value1</link>
    </Name>
    <Name>
        <All> Filter</All>
        <link>value2</link>
    </Name>
</Generic_Name>

enter image description here

Resources:

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
1

You should try a more object-oriented approach.

You should create an object called NameEntity, and inside it have the properties All and Link.

Iterate over your XML and create an arrayList of NameEntities.

Now iterate over the arrayList and add the elements to your combobox. You can either implement toString() to make NameEntity print the All attribute, or you can use a ListCellRenderer to explicitly render the value of NameEntitiy.

Read up here :

http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html

Now in actionPerformed(..) you will get a NameEntity instead of a String. To get the corresponding Link value, you just have to call

NameEntity ne = (NameEntity)assignCombo.getSelectedItem();
ne.getLink();
Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225