Reputation: 5359
I've been trying to build an app on Android that gets data from a Labview RestFUL server. I've been able to accomplish a fair bit so far but I'm stuck when I need parse data from an array (named Probability). A snippet of the XML code is shown:
<Response>
<Terminal>
<Name>Push</Name>
<Value>77.678193</Value>
</Terminal>
<Terminal>
<Name>Pull</Name>
<Value>153.621879</Value>
</Terminal>
(snip)
<Terminal>
<Name>Probability</Name>
<Value>
<DimSize>480</DimSize>
<Name>effect</Name>
<Value>0.000000</Value>
<Name>effect</Name>
<Value>0.000000</Value>
<Name>effect</Name>
(snip)
</Value>
</Terminal>
</Response>
As you can see LabView uses a nested value tag.
I've been using standard XML parsing techniques and that hasn't worked (If I search for "Values" in the parent node it returns that same parent node). So I'm starting to use more creative techniques with no good results. For instance the code below, I call if ( lName == "Value")
only to find lName is set to Null.
Any advice out there?
InputStream firstData = null;
URL url = null;
try {
url = new URL(urlString);
} catch (MalformedURLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
int response = -1;
try {
URLConnection conn = url.openConnection();
Document doc = null;
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db;
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
firstData = httpConn.getInputStream();
}
try {
db = dbf.newDocumentBuilder();
doc = db.parse(firstData);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
doc.getDocumentElement().normalize();
NodeList terminalNodes = doc.getElementsByTagName("Terminal");
for (int i = 0; i < 4; i++) {
Node singleTerminalNode = terminalNodes.item(i);
if (singleTerminalNode.getNodeType() == Node.ELEMENT_NODE)
{
Element firstLevel = (Element) singleTerminalNode;
NodeList value1Nodes = (firstLevel).getElementsByTagName("Value");
Element value1Element = (Element) value1Nodes.item(0);
if (i<FIRST_SET){
NodeList digit1Nodes = ((Node) value1Element).getChildNodes();
hinde[i] = Double.parseDouble(((Node) digit1Nodes.item(0)).getNodeValue());
}
else
{
NodeList value1Children = ((Node) value1Element).getChildNodes();
int henry = value1Children.getLength();
int counter = 0;
String lName;
for (int j = 0; i < henry; j++){
Element digit2Element = (Element) value1Children.item(j);
lName = digit2Element.getLocalName();
if ( lName == "Value")
{
NodeList digit2Nodes = ((Node) digit2Element).getChildNodes();
sweep[counter] = Double.parseDouble(((Node) digit2Nodes.item(0)).getNodeValue());
counter ++;
}
}
}
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Upvotes: 1
Views: 3588
Reputation: 2579
As nicholas.hauschild mentioned, you can use the SAX Parser to do this. But I don't think you need the level variable to distinguish the two tags.
Whenever there is data to be read, it will call the characters() method and you can read the values off of that. Since the parent <Value>
tag doesn't have any data of it's own (apart from the nested tags), it doesn't call the characters() method.
Upvotes: 0
Reputation: 42849
I imagine this can be done with a DOM parser, but it may be easier to implement with a SAX or STAX parser (it will also have a smaller memory imprint!).
http://download.oracle.com/javase/1.4.2/docs/api/javax/xml/parsers/SAXParser.html
http://download.oracle.com/javaee/5/tutorial/doc/bnbem.html
With SAX, you create a handler that will receive events as the parser reaches certain points in the document. With tags that can be embedded, you could use your handler to maintain the state of the cursor. For example, when you see the first tag, you could have an int representing the 'level' of the tag.
With STAX, you stream the events and only need to deal with the events that you are interested in. If you are interested in 'start element events', you can get them, and keep the state of the cursor similar to how you would with a SAX parser.
Upvotes: 2