I'm struggling with how to use XPath on KML files that contain the new gx:Track and gx:coord tags. The problem is with how to use XPath with namespaces under Android.
I've looked at a number of examples, including these
https://www.ibm.com/developerworks/library/x-nmspccontext/index.html
https://howtodoinjava.com/xml/xpath-namespace-resolution-example/
XPath with namespace in Java
NamespaceContext and using namespaces with XPath
but I can't seem to get even those examples to work.
The following code and output illustrates my problem:
public App() {
super();
try {
test( testDoc1() );
test( testDoc2() );
} catch( Exception e ) {
e.printStackTrace();
} finally {
Log.d( "TEST-FINISHED", "test is finished" );
}
}
private String toXmlString( Document document ) throws TransformerException {
DOMSource domSource = new DOMSource( document );
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult( writer );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform( domSource, result );
return writer.toString();
}
private Document testDoc1() throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware( true );
Document mDocument = documentBuilderFactory.newDocumentBuilder().newDocument();
String XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
Element mKmlElement = mDocument.createElement( "kml" );
mKmlElement.setAttributeNS( XMLNS_NAMESPACE_URI, "xmlns", "http://www.opengis.net/kml/2.2" );
mKmlElement.setAttributeNS( XMLNS_NAMESPACE_URI, "xmlns:gx", "http://www.google.com/kml/ext/2.2" );
mDocument.appendChild( mKmlElement );
Element mPlacemarkElement = mDocument.createElement( "Placemark" );
mKmlElement.appendChild( mPlacemarkElement );
Element gxTrackElement = mDocument.createElement( "gx:Track" );
mPlacemarkElement.appendChild( gxTrackElement );
Element gxCoordElement = mDocument.createElement( "gx:coord" );
gxCoordElement.setTextContent( "-122.207881 37.371915 156.000000" );
gxTrackElement.appendChild( gxCoordElement );
return mDocument;
}
private Document testDoc2() throws ParserConfigurationException, IOException, SAXException {
String kmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\"><Placemark><gx:Track><gx:coord>-122.207881 37.371915 156.000000</gx:coord></gx:Track></Placemark></kml>";
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware( true );
Document mDocument = documentBuilderFactory.newDocumentBuilder().parse( new InputSource( new StringReader( kmlString ) ) );
return mDocument;
}
private void test( Document mDocument ) throws Exception {
String xml = toXmlString( mDocument );
Log.d( "TEST-XML", xml );
XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext( new NamespaceContext() {
#Override
public String getNamespaceURI( String prefix ) {
switch( prefix ) {
case XMLConstants.DEFAULT_NS_PREFIX:
return "http://www.opengis.net/kml/2.2";
case "gx":
return "http://www.google.com/kml/ext/2.2";
}
return XMLConstants.NULL_NS_URI;
}
#Override
public String getPrefix( String namespaceURI ) {
return null;
}
#Override
public Iterator getPrefixes( String namespaceURI ) {
return null;
}
} );
NodeList result1 = (NodeList) xPath.evaluate( "/kml", mDocument, XPathConstants.NODESET );
Log.d( "TEST-RESULT1", String.valueOf( result1.getLength() ) );
NodeList result2 = (NodeList) xPath.evaluate( "/kml/Placemark", mDocument, XPathConstants.NODESET );
Log.d( "TEST-RESULT2", String.valueOf( result2.getLength() ) );
NodeList result3 = (NodeList) xPath.evaluate( "/kml/Placemark/gx:Track", mDocument, XPathConstants.NODESET );
Log.d( "TEST-RESULT3", String.valueOf( result3.getLength() ) );
}
The test() method executes 3 XPath statements/patterns and is called once for each of two test documents. The 2 documents are constructed using different methods but the contents should be identical. However, the results I get from the 3 XPath statements are different.
These are the results with document 1:
2018-11-17 17:51:28.289 22837-22837/ca.csdesigninc.offroadtracker D/TEST-XML: <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"><Placemark><gx:Track><gx:coord>-122.207881 37.371915 156.000000</gx:coord></gx:Track></Placemark></kml>
2018-11-17 17:51:28.324 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT1: 1
2018-11-17 17:51:28.334 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT2: 1
2018-11-17 17:51:28.343 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT3: 0
and these are the results with document 2:
2018-11-17 17:51:28.348 22837-22837/ca.csdesigninc.offroadtracker D/TEST-XML: <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"><Placemark><gx:Track><gx:coord>-122.207881 37.371915 156.000000</gx:coord></gx:Track></Placemark></kml>
2018-11-17 17:51:28.358 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT1: 0
2018-11-17 17:51:28.363 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT2: 0
2018-11-17 17:51:28.372 22837-22837/ca.csdesigninc.offroadtracker D/TEST-RESULT3: 0
There are at least 2 problems:
since the 2 documents are identical (I think), why are the results of the tests different? (i.e., the first 2 XPath statements succeed with document 1 but neither succeeds with document 2.)
and why does the 3rd XPath statement fail to find the gx:Track element in both document 1 and document 2?
UPDATE: This problem seems to have something to do with having
xmlns="http://www.opengis.net/kml/2.2"
included in document 2. If I remove it, the results of the first 2 XPath tests are the correct (for both documents) - and in fact XPath test 3 now works on document 2. Unfortunately, I still don't have a handle on this behavior.
I'm probably missing something obvious and would appreciate any help.
The differences are due to namespaces. Both in how the XML is being produced, and when you are selecting content in the XPath.
Unfortunately, it is difficult to see the difference because the XML that happens to be serialized by the toXmlString() for testDoc1() doesn't exactly match the state of the in-memory document.
When you construct the kml element, using createElement() it creates an element that is bound to the "no namespace". Then, you added namespace attributes, which happen to come out when serializing with toXmlString() and make the kml element appear to be in the http://www.opengis.net/kml/2.2 namespace.
If you were to marshal that XML back to a new Document object, the kml element would be bound to that namespace. However, the current in-memory object for that element is not.
You can observe this by adding some additional diagnostics println messages:
NodeList result1 = (NodeList) xPath.evaluate("/kml", mDocument, XPathConstants.NODESET);
System.out.println(String.valueOf(result1.getLength()));
System.out.println("Namespace URI: " + result1.item(0).getNamespaceURI());
System.out.println("Prefix: " + result1.item(0).getPrefix());
You can round-trip your XML and observe that it behaves different when you marshall the serialized XML:
private void test(Document mDocument) throws Exception {
String xml = toXmlString(mDocument);
System.out.println( xml);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
mDocument = documentBuilderFactory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
However, that's cheating. What you really want to do is ensure that the elements are created properly in the first place. When you create an element that you want to be bound to a namespace, use the createElementNS() method, as indicated in the JavaDoc comments for createElement():
To create an element with a qualified name and namespace URI, use the createElementNS method.
So, to create an element that is bound to the http://www.opengis.net/kml/2.2 namespace, you would want to use:
Element mKmlElement = mDocument.createElementNS("http://www.opengis.net/kml/2.2", "kml");
and:
Element mKmlElement = mDocument.createElementNS("http://www.opengis.net/kml/2.2", "Placemark");
and the same goes for the gx:Track element:
Element gxTrackElement = mDocument.createElementNS("http://www.google.com/kml/ext/2.2","gx:Track");
Once you get your Document objects truly equal and correct, you then need to adjust your XPath.
With XPath, if you don't apply a namespace prefix, it will select elements bound to the "no namespace". So, /kml will only select kml elements that are not bound to a namespace. But since your kml elements are bound to the http://www.opengis.net/kml/2.2 namespace, it won't select them.
In your override of the getNamespaceURI() function, you could reserve gx for the Google KML Extension namespace, and then default any other namespace-prefix to resolve to http://www.opengis.net/kml/2.2:
#Override
public String getNamespaceURI(String prefix) {
return "gx".equals(prefix) ? "http://www.google.com/kml/ext/2.2" : "http://www.opengis.net/kml/2.2";
}
Then, adjust your XPath statements to use a prefix for those KML elements. If you use the above code, it doesn't matter what prefix you use. Anything other than gx will return the http://www.opengis.net/kml/2.2 namespace.
NodeList result1 = (NodeList) xPath.evaluate("/k:kml", mDocument, XPathConstants.NODESET);
System.out.println(String.valueOf(result1.getLength()));
System.out.println("Namespace URI: " + result1.item(0).getNamespaceURI());
System.out.println("Prefix: " + result1.item(0).getPrefix());
NodeList result2 = (NodeList) xPath.evaluate("/k:kml/k:Placemark", mDocument, XPathConstants.NODESET);
System.out.println( String.valueOf(result2.getLength()));
NodeList result3 = (NodeList) xPath.evaluate("/k:kml/k:Placemark/gx:Track", mDocument, XPathConstants.NODESET);
System.out.println(String.valueOf(result3.getLength()));
Putting it all together:
public App() {
super();
try {
test( testDoc1() );
test( testDoc2() );
} catch( Exception e ) {
e.printStackTrace();
} finally {
Log.d( "TEST-FINISHED", "test is finished" );
}
}
private String toXmlString(Document document) throws TransformerException {
DOMSource domSource = new DOMSource(document);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
return writer.toString();
}
private Document testDoc1() throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
Document mDocument = documentBuilderFactory.newDocumentBuilder().newDocument();
String XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
//Element mKmlElement = mDocument.createElement("kml");
Element mKmlElement = mDocument.createElementNS("http://www.opengis.net/kml/2.2", "kml");
//mKmlElement.setAttributeNS(XMLNS_NAMESPACE_URI, "xmlns", "http://www.opengis.net/kml/2.2");
mKmlElement.setAttributeNS(XMLNS_NAMESPACE_URI, "xmlns:gx", "http://www.google.com/kml/ext/2.2");
mDocument.appendChild(mKmlElement);
//Element mPlacemarkElement = mDocument.createElement("Placemark");
Element mPlacemarkElement = mDocument.createElementNS("http://www.opengis.net/kml/2.2", "Placemark");
//mPlacemarkElement.setAttributeNS(XMLNS_NAMESPACE_URI, "xmlns", "http://www.opengis.net/kml/2.2");
mKmlElement.appendChild(mPlacemarkElement);
//Element gxTrackElement = mDocument.createElement("gx:Track");
Element gxTrackElement = mDocument.createElementNS("http://www.google.com/kml/ext/2.2","gx:Track");
mPlacemarkElement.appendChild(gxTrackElement);
//Element gxCoordElement = mDocument.createElement("gx:coord");
Element gxCoordElement = mDocument.createElementNS("http://www.google.com/kml/ext/2.2", "gx:coord");
gxCoordElement.setTextContent("-122.207881 37.371915 156.000000");
gxTrackElement.appendChild(gxCoordElement);
return mDocument;
}
private Document testDoc2() throws ParserConfigurationException, IOException, SAXException {
String kmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\"><Placemark><gx:Track><gx:coord>-122.207881 37.371915 156.000000</gx:coord></gx:Track></Placemark></kml>";
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
Document mDocument = documentBuilderFactory.newDocumentBuilder().parse(new
InputSource(new StringReader(kmlString)));
return mDocument;
}
private void test(Document mDocument) throws Exception {
String xml = toXmlString(mDocument);
System.out.println( xml);
XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
#Override
public String getNamespaceURI(String prefix) {
return "gx".equals(prefix) ? "http://www.google.com/kml/ext/2.2" : "http://www.opengis.net/kml/2.2";
}
#Override
public String getPrefix(String namespaceURI) {
if ("http://www.google.com/kml/ext/2.2".equals(namespaceURI)) {
return "gx";
}
return null;
}
#Override
public Iterator getPrefixes(String namespaceURI) {
List<String> ns = new ArrayList<>();
ns.add("gx");
return ns.iterator();
}
});
NodeList result1 = (NodeList) xPath.evaluate("/k:kml", mDocument, XPathConstants.NODESET);
System.out.println(String.valueOf(result1.getLength()));
System.out.println("Namespace URI: " + result1.item(0).getNamespaceURI());
System.out.println("Prefix: " + result1.item(0).getPrefix());
NodeList result2 = (NodeList) xPath.evaluate("/k:kml/k:Placemark", mDocument, XPathConstants.NODESET);
System.out.println( String.valueOf(result2.getLength()));
NodeList result3 = (NodeList) xPath.evaluate("/k:kml/k:Placemark/gx:Track", mDocument, XPathConstants.NODESET);
System.out.println(String.valueOf(result3.getLength()));
}
I'm looking for ways to read a generic xml file
Here is an example of a normal xml file
<?xml version="1.0"?>
<students>
<student>
<name>John</name>
<grade>B</grade>
<age>12</age>
</student>
<student>
<name>Mary</name>
<grade>A</grade>
<age>11</age>
</student>
<student>
<name>Simon</name>
<grade>A</grade>
<age>18</age>
</student>
</students>
and here is example of a typical xml parser that would read that code and print it out
public class XMLParser {
public void getAllUserNames(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File(fileName);
if (file.exists()) {
Document doc = db.parse(file);
Element docEle = doc.getDocumentElement();
// Print root element of the document
System.out.println("Root element of the document: "
+ docEle.getNodeName());
NodeList studentList = docEle.getElementsByTagName("student");
// Print total student elements in document
System.out
.println("Total students: " + studentList.getLength());
if (studentList != null && studentList.getLength() > 0) {
for (int i = 0; i < studentList.getLength(); i++) {
Node node = studentList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out
.println("=====================");
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("name");
System.out.println("Name: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("grade");
System.out.println("Grade: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("age");
System.out.println("Age: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
}
}
} else {
System.exit(1);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
XMLParser parser = new XMLParser();
parser.getAllUserNames("c:\\test.xml");
}
}
This code needs lines like this
NodeList studentList = docEle.getElementsByTagName("student");
NodeList nodeList = e.getElementsByTagName("name");
In order to work correctly.
My questions comes from how would I make that generic. Is there any way where I could read that same XML file without having to get specific elements by tagNames and yet still print it out in a view able format.
In the above example you are using Dom parser. By using Jaxb Context unmarshaller you can convert the xml to java object, then you can achive your task.
You need to have a generic function to handle.
Generic function is as follows:
/* Prints the Node Value */
public void PrintNodeValue(Element element, String tagName, String msg)
{
NodeList nodeList = element.getElementsByTagName(tagName);
System.out.println(msg + nodeList.item(0).getChildNodes().item(0).getNodeValue());
}
Function is called as below:
PrintNodeValue(e, "name", "Name: ");
PrintNodeValue(e, "grade", "Grade: ");
I use XML XPath API in my application
This is my soap request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tes="http://testwork/">
<soapenv:Header/>
<soapenv:Body>
<tes:sayHelloWorldFrom>
<!--Optional:-->
<arg0>value</arg0>
</tes:sayHelloWorldFrom>
</soapenv:Body>
</soapenv:Envelope>
I want to retrieve the body from this message, thus I want to have
<soapenv:Body>
<tes:sayHelloWorldFrom>
<!--Optional:-->
<arg0>value</arg0>
</tes:sayHelloWorldFrom>
</soapenv:Body>
My piece of code looks like
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
org.w3c.dom.Document doc = null;
try {
doc = factory.newDocumentBuilder().parse(is);
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
Object result = xPath.compile("/soapenv:Envelope/soapenv:Body").evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
log.info("result " + nodes);
But the result is result com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList#19f76837
So what am I doing wrong?
XPathConstants.NODESET instructs the API to return a NodeList of the results it finds matching the query.
This is useful when you are expecting a variable number of matches. You can iterate over the list...
for (int index = 0; index < nodes.getLength(); index++) {
Node node = nodes.item(index);
//...
}
If you are confident that you will only receive a single result (or you just want the first match), you can use XPathConstants.NODE instead
Object result = xPath.compile("/soapenv:Envelope/soapenv:Body").evaluate(doc, XPathConstants.NODE);
Node node = (Node)result;
Updated
There's probably away to do this without doing the following, but name spaces do my head...
After you create the factory, set it's name space awareness tofalse`, then drop the node name space context from your search, for example...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
org.w3c.dom.Document doc = null;
try {
doc = factory.newDocumentBuilder().parse(new File("Soap.xml"));
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
Object result = xPath.compile("/Envelope/Body").evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
System.out.println("Found " + nodes.getLength() + " matches");
for (int index = 0; index < nodes.getLength(); index++) {
Node node = nodes.item(index);
System.out.println(node);
}
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException exp) {
exp.printStackTrace();
}
I have a SOAP Response as below
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NTService.DisconnectResourceResult xmlns="http://www.evolving.com/NumeriTrack/xsd">
<retData xmlns="">
<retCode>rcSuccess</retCode>
<retMsg/>
<resErrList/>
</retData>
</NTService.DisconnectResourceResult>
</soapenv:Body>
</soapenv:Envelope>
Am not good in generating XPATH query, but using SOAPUI I was able to fetch the XPATH query to fetch retCode as below :
//ns1:NTService.DisconnectResourceResult[1]/retData[1]/retCode[1]/text()
In Java, am trying to fetch retCode but am unable to fetch the output.
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new SoapNamespaceContext());
String sxpath="//ns1:NTService.DisconnectResourceResult[1]/retData[1]/retCode[1]/text()";
System.out.println("sxpath is " + sxpath);
XPathExpression expr;
expr = xpath.compile(sxpath);
System.out.println("expr is " + expr);
Object result;
result = expr.evaluate(sb, XPathConstants.NODESET);
System.out.println("result is " + result);
NodeList nodes = (NodeList) result;
System.out.println("Length of result is " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
}
I have set the namespace as well.
public String getNamespaceURI(String prefix) {
System.out.println("Prefix is " +prefix);
if (prefix == null) throw new NullPointerException("Null prefix");
else if ("ns1".equals(prefix)) {
System.out.println("Returning http://www.evolving.com/NumeriTrack/xsd");
return "http://www.evolving.com/NumeriTrack/xsd";
}
else if ("n".equals(prefix)) {
System.out.println("Returning http://schemas.xmlsoap.org/soap/envelope/");
return "http://schemas.xmlsoap.org/soap/envelope/";
}
else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI;
return XMLConstants.NULL_NS_URI;
}
`
Can anyone please suggest me to get retCode from the SOAP Message response.
Thanks
Here's the anserw :
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));
System.out.println(doc.getElementsByTagName("retCode").item(0).getTextContent());
You should use .getTextContent() method.
Will output rcSuccess as you want :)
Hope it's helps,
I have this project I'm working on where I want to parse an xml file that looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<projectlist>
<project>
<name>SuperDuperApp</name>
<type>batch</type>
<prod>
<server>testserver01</server>
</prod>
<qa>
<server>testserver01</server>
</qa>
<dev>
<server>testserver01</server>
</dev>
</project>
<project>
<name>Calculator</name>
<type>deploy</type>
<prod>
<server>testserver02</server>
<server>testserver03</server>
<server>testserver04</server>
</prod>
<qa>
<server>testserver05</server>
<server>testserver06</server>
<server>testserver07</server>
</qa>
<dev>
<server>testserver12</server>
<server>testserver13</server>
<server>testserver14</server>
</dev>
</project>
</projectlist>
With this method parsing the file and trying to print out in the format:
name: SuperDuperApp
type: batch
server: testserver01
name: Calculator
type: deploy
environment: dev
server: testserver12
server: testserver13
server: testserver14
etc.
public void parseXML() {
ArrayList al = new ArrayList();
HashSet hs = new HashSet();
try {
InputStream file = this.getClass().getResourceAsStream(
"/net/swing/sandbox/util/config/projectlist.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("project");
System.out.println("Information of all servers...");
for (int i=0;i<nList.getLength();i++){
Node fstNode = nList.item(i);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElement = (Element) fstNode;
NodeList nameElementList = fstElement.getElementsByTagName("name");
Element nameElement = (Element) nameElementList.item(0);
NodeList name = nameElement.getChildNodes();
System.out.println("project name: " + ((Node) name.item(0)).getNodeValue());
hs.add(((Node) name.item(0)).getNodeValue());
NodeList typeElementList = fstElement.getElementsByTagName("type");
Element typeElement = (Element) typeElementList.item(0);
NodeList type = typeElement.getChildNodes();
System.out.println("Deploy type: " + ((Node) type.item(0)).getNodeValue());
//print out server list can't do it for some reason
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
al.clear();
al.addAll(hs);
Collections.sort(al);
for (int z = 0; z < al.size(); z++) {
listModel.addElement(al.get(z));
}
} catch (Exception e) {
e.printStackTrace();
}
lstProject.validate();
}
So I rewrote my method and now I'm just stuck <---newb
Check the documentation for Node. Each node has a method getChildNodes. Check that for the existence of children nodes and than iterate over them like you are doing.
If your xml was created using an xsd schema, you could instead use JAXB to create classes for it, using the xjc tool. That should make your life a bit easier.
I think it's appropriate to use XSLT transform in your case (much less boilerplate code) Look at TransformerFactory and java api for xml processing.
As a q&d solution you could apply the same strategy as for getting "project" node:
...
System.out.println("servers:");
NodeList sList = eElement.getElementsByTagName("server");
for (int i = 0; i < sList.getLength(); i++) {
String stuff = sList.item(i).getFirstChild().getNodeValue();
System.out.println(stuff);
}