Search code examples
javaxmlxml-parsingdocumenthelper

how to get specific tag content inside parant tag from id in xml using java?


I have an XML file as below. I want to get its specific child tag from the parent tag using java.

<?xml version="1.0"?>  
<class>  
    
  <question  id="scores">
        <ans>12</ans>
        <ans>32</ans>
        <ans>44</ans>
  </question>

  <question  id="ratings">
        <ans>10</ans>
        <ans>22</ans>
        <ans>45</ans>
        <ans>100</ans>
  </question>
<default>
    Sorry wrong
</default>
  </class>  

i want the function to be like this

String function(String id)

it will return the ans tag randomly
i.e if I give input id=scores, the program will look in the XML tag for scores as id and get length()of its children, in this case, 3, then retun randomly like 32 or 44 or 12.if id is not present, return default.

my code so far

public class ChatBot {
    
    private String filepath="E:\\myfile.xml";
    private File file;
    private Document doc;

    public ChatBot() throws SAXException, IOException, ParserConfigurationException {
         file = new File("E:\\myfile.xml");  
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
         DocumentBuilder db = dbf.newDocumentBuilder();  
         doc = db.parse(file); 
    }
    
    
    String Function(String id){
// This part
            return null;
    }
       
    }

Solution

  • As suggested by @LMC (because of org.w3c.dom.Document.getElementById() not recognizing arbitrary id attributes as IDs for getElementById() or as a browser would, mostly for HTML semantics/format), maybe:

        String Function(String id) throws XPathExpressionException {
            XPath xPath = XPathFactory.newInstance().newXPath();
            // Be aware: id inserted without any escaping!
            NodeList parents = (NodeList)xPath.evaluate("/class/question[@id='" + id + "']", doc, XPathConstants.NODESET);
    
            if (parents.getLength() < 1) {
                return null;
            } else if (parents.getLength() > 1) {
                // Huh, duplicates?
            }
    
            Element parent = (Element)parents.item(0);
            NodeList children = parent.getChildNodes();
    
            List<Element> answers = new ArrayList<Element>();
    
            for (int i = 0, max = children.getLength(); i < max; i++) {
                if (children.item(i).getNodeType() != Node.ELEMENT_NODE) {
                    continue;
                }
    
                if (children.item(i).getNodeName().equals("ans") != true) {
                    // Huh?
                    continue;
                }
    
                answers.add((Element)children.item(i));
            }
    
            if (answers.size() <= 0) {
                return null;
            }
    
            int selection = (int)(Math.random() * answers.size());
    
            return answers.get(selection).getTextContent();
        }