Svj0hn
Svj0hn

Reputation: 454

Java: Parse XML child element that may not exist

I'm trying to extract values from an InputStream containing XML data. The general data layout is something like this:

<objects count="1">
    <object>
        <stuff>...</stuff>
        <more_stuff>...</more_stuff>
        ...
        <connections>
            <connection>124</connection>
            <connection>128</connection>
        </connections>
    </object>
<objects>

I need to find the integers stored in the <connection> attributes. However, I can't guarantee that there will always be exactly two (there may be just one or none at all). Even more, there will be cases where the element <connections> is not present.

I've been looking at examples like this, but it doesn't mention how to handle cases where a parent is non-existent.

The case where <connections> doesn't exist at all is quite rare (but is something I definitely need to know when it does happen), and the case where it does exist but contains less than two <connection>'s would be even more rare (basically I expect it to never happen).

Should I just assume everything is in place and catch the exception if something happens, or is there a clever way to detect the presence of <connections>?

My initial idea was to use something like:

InputStream response = urlConnection.getInputStream();

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(response);

String xPathExpressionString = "/objects/object/connections/connection";

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression expr = xPath.compile(xPathExpressionString);

NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

for (int i = 0; i < nodeList.getLength(); i++) {
    Node intersectionNode = nodeList.item(i);
    if (intersectionNode.getNodeType() == Node.ELEMENT_NODE) { // What is this anyway?
        // Do something with value
    }
}

According to the example linked above, this should handle the case with varying amounts of <connection>'s, but how should I deal with <connections> missing alltoghether.

(Btw, there should always only be a single object, so no need to worry about that)

Upvotes: 1

Views: 908

Answers (2)

forty-two
forty-two

Reputation: 12817

Use this xpath expression:

   "//object//connection"

The "//" construct is a short form for the "self-or-descendants" axis. So the expression above will select all <connection> elements that have an <object> parent.

Upvotes: 1

nagalla pruthvi
nagalla pruthvi

Reputation: 55

From the below code we can get all the names of child tags of a document and once we it goes into second if block it means there is connections tag existing as childnode for given doc:
As you said we don't know information about the parent we can use the below line accordingly to the xml present.
group.getChildNodes().item(0).getChildNodes()......

Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
NodeList groupList = doc.getChildNodes().item(0).getChildNodes();
for (int groupCount = 0; groupCount < groupList.getLength(); groupCount++)
 {
            Node group = groupList.item(groupCount);
            if (group.getNodeType() == Node.ELEMENT_NODE)
              {
                    if(group.getNodeName().equals("connections"))
                      {
                      }  
              }
}

My First Answer in Stackoverflow.Hope this helps.

Upvotes: 0

Related Questions