使用相同的父标签和子标签解析 Java 中的 XML
我一直在尝试在 Android 上构建一个从 Labview RestFUL 服务器获取数据的应用程序。到目前为止,我已经完成了相当多的工作,但是当我需要从数组(名为概率)解析数据时,我陷入了困境。显示了 XML 代码片段:
<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>
如您所见,LabView 使用嵌套值标签。
我一直在使用标准 XML 解析技术,但这并没有起作用(如果我在父节点中搜索“Values”,它会返回相同的父节点)。所以我开始使用更多的创造性技术,但没有取得好的结果。例如下面的代码,我调用 if ( lName == "Value")
只是发现 lName 设置为 Null。
有什么建议吗?
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();
}
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想这可以使用 DOM 解析器来完成,但使用 SAX 或 STAX 解析器可能更容易实现(它也会有更小的内存印记!)。
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
使用 SAX,您可以创建一个处理程序,当解析器到达某些点时,该处理程序将接收事件该文件。通过可以嵌入的标签,您可以使用处理程序来维护光标的状态。例如,当您看到第一个标签时,您可以使用一个 int 来表示该标签的“级别”。
使用 STAX,您可以流式传输事件,并且只需要处理您感兴趣的事件。如果您对“开始元素事件”感兴趣,您可以获取它们,并保持光标的状态类似于您使用的方式SAX 解析器。
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.
正如 nicholas.hauschild 提到的,您可以使用 SAX 解析器来执行此操作。但我认为你不需要 level 变量来区分这两个标签。
每当有数据要读取时,它都会调用 strings() 方法,您可以从中读取值。由于父
标记没有自己的任何数据(除了嵌套标记之外),因此它不会调用 strings() 方法。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.