Using the following sample to parse an XML file. Able to get it working with samples taken from various places, but it doesn't explain to me why the following fails which is the objective of this post.
Here is the code being executed.
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLQuestions
{
public static void main(String argv[])
{
try
{
String filepath = "c:\\Downloads\\DummyData.xml";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
doc.setXmlStandalone(true);
NodeList allDeliveryLocations = doc.getElementsByTagName("DeliveryLocations");
for(int j=0; j < allDeliveryLocations.getLength();j++)
{
Element deliveryLocationElement = (Element) allDeliveryLocations.item(j);
Node deliveryLocationNode = (Node) allDeliveryLocations.item(j);
System.out.println("Get Element & Node Name");
System.out.println(" deliveryLocationElement : " + deliveryLocationElement.getNodeName());
System.out.println(" deliveryLocationNode : " + deliveryLocationNode.getNodeName());
System.out.println("");
System.out.println("GetFirstChild()");
Node deliveryLocationChild = deliveryLocationNode.getFirstChild();
System.out.println(" Node Name : " + deliveryLocationChild.getNodeName());
System.out.println(" Node Value : " + deliveryLocationChild.getNodeValue() );
System.out.println("");
System.out.println("GetNextSibling()");
deliveryLocationChild = deliveryLocationChild.getNextSibling();
System.out.println(" Node Name : " + deliveryLocationChild.getNodeName());
System.out.println(" Node Value : " + deliveryLocationChild.getNodeValue());
System.out.println("");
}
System.out.println("Done");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
}
catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
}
}
Sample XML used for testing.
<?xml version="1.0" encoding="UTF-8"?>
<AllStorage>
<NorthAmerica>
<EastCoast>
<DeliveryLocations>
<Location>North East </Location>
<Item1>Full</Item1>
<Item2>Empty</Item2>
<Item3 attr1="1" attr2="2" />
<Item4 istransferable="true">
<States>
<State>
<NewYork>
<UpTown>
<TimeOfDelivery>Morning</TimeOfDelivery>
<DeliveryLocation>back</DeliveryLocation>
</UpTown>
</NewYork>
</State>
<State>
<NewYork>
<UpTown>
<TimeOfDelivery>Evening</TimeOfDelivery>
<DeliveryLocation>side</DeliveryLocation>
</UpTown>
</NewYork>
</State>
<State>
<NewYork>
<UpTown>
<TimeOfDelivery>Afternoon</TimeOfDelivery>
<DeliveryLocation>front</DeliveryLocation>
</UpTown>
</NewYork>
</State>
</States>
</Item4>
</DeliveryLocations>
<DeliveryLocations>
<Location>South East </Location>
<Item1>Totally Full </Item1>
<Item2>Half Empty</Item2>
<Item3 attr1="5" attr2="6" />
<Item4 istransferable="true">
<States>
<State>
<Florida>
<UpTown>
<TimeOfDelivery>Early Morning</TimeOfDelivery>
<DeliveryLocation>front</DeliveryLocation>
</UpTown>
</Florida>
</State>
<State>
<Florida>
<UpTown>
<TimeOfDelivery>MidDay</TimeOfDelivery>
<DeliveryLocation>back</DeliveryLocation>
</UpTown>
</Florida>
</State>
<State>
<Florida>
<UpTown>
<TimeOfDelivery>Midnight</TimeOfDelivery>
<DeliveryLocation>back</DeliveryLocation>
</UpTown>
</Florida>
</State>
</States>
</Item4>
</DeliveryLocations>
</EastCoast>
</NorthAmerica>
</AllStorage>
Executing these lines, helps to see that either an Element or Node can be used.
Element deliveryLocationElement = (Element) allDeliveryLocations.item(j);
Node deliveryLocationNode = (Node) allDeliveryLocations.item(j);
Here is the output generated from the above.
Question 1 :
What determines whether to use an Element or Node? Would it be what ever methods one expects to execute or data to retrieve?
Next, the following lines of code are executed.
System.out.println("GetFirstChild()");
Node deliveryLocationChild = deliveryLocationNode.getFirstChild();
System.out.println(" Node Name : " + deliveryLocationChild.getNodeName());
System.out.println(" Node Value : " + deliveryLocationChild.getNodeValue() );
System.out.println("");
Here is the output generated.
Since Location is the child of DeliveryLocations, I was expected to see
Node Name : Location
Node Value : North East
Question 2 :
Why didn't getFirstChild() return Location as expected? Is there an additional call required?
Next, the following lines of code are executed.
System.out.println("GetNextSibling()");
deliveryLocationChild = deliveryLocationChild.getNextSibling();
System.out.println(" Node Name : " + deliveryLocationChild.getNodeName());
System.out.println(" Node Value : " + deliveryLocationChild.getNodeValue());
System.out.println("");
Here is the output generated.
Ok, this time I get Location printed out, but it was after a getNextSibling() and still the value is null.
Question 3 :
Why was it required to call both getFirstChild() and getNextSibling() in order to see the first chile?
Why didn't getNextSibling() print out Item1 instead of null?
I think getting the answers to these question will help with a better understanding of what is happening and why certain calls are required.


