Android - XML解析 - 在模拟器上工作但不在设备上工作

时间:2011-05-05 17:34:50

标签: android xml dom xml-parsing

在我的应用程序中,我正在解析xml,一块结构出现问题:

<answers>
    <answer value="A">A</answer>
    <answer value="B">B</answer>
    <answer value="C">C</answer>
</answers>

我正在使用XML DOM解析它:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();

效果很好,根据答案项目我正在创建一个像这样的RadioButtons:

NodeList answers = doc.getElementsByTagName("answers").item(0).getChildNodes();

int j = 0;
RadioGroup group = new RadioGroup(this);
RadioButton button1 = new RadioButton(this);
button1.setId((i+1)*100+(j++));
button1.setText(answers.item(1).getChildNodes().item(0).getNodeValue());
button1.setTextColor(Color.BLACK);

RadioButton button2 = new RadioButton(this);
button2.setId((i+1)*100+(j++));
button2.setText(answers.item(2).getChildNodes().item(0).getNodeValue());
button2.setTextColor(Color.BLACK);

RadioButton button3 = new RadioButton(this);
button3.setId((i+1)*100+(j));
button3.setText(answers.item(3).getChildNodes().item(0).getNodeValue());
button3.setTextColor(Color.BLACK);

这段代码在模拟器SDK V.7(Android 2.0)中完美运行,而我的HTC Desire在Android 2.1u1上运行(所以SDK v.8)

但是在设备中我得到错误button2.setText(answers.item(2).getChildNodes().item(0).getNodeValue());猜测答案中没有.item(2) - 但它必须是...我在模拟器中调试此代码并发现answers.item(0)TextNode,其中包含XML节点的名称“answers”...

但是我确实有点困惑,在解析这个XML时一切都搞乱了,因为我仍然需要计算我有多深,何时调用哪个元素(节点)的索引......但是我仍然是发现这个实现比使用SAX ...

简单得多

Java中的PHP SimpleXml是不是有类似的东西

无论如何,我的主要问题是:应用程序如何在模拟器中完美运行,而在设备上它会在我尝试为button2设置文本的行上抛出NullPointerException ???

非常感谢你的帮助!!!

2 个答案:

答案 0 :(得分:2)

getChildNodes()返回答案下的所有Node,而不只是所有Element。您可能希望遍历所有子项并检查每个子项是否为Element,标记名称为“answer”

这样的事情怎么样:

NodeList answers = doc.getElementsByTagName("answer");
for (int x = 0; x < answers.getLength(); x++) {
  Node answer = answers.get(x);
  // you could do some checking here, make sure Node is instanceof Element, etc.
  RadioButton radioButton = new RadioButton(this);
  radioButton.setId((i+1)*100+(x));
  radioButton.setText(node.getNodeValue());
  radioButton.setTextColor(Color.BLACK);
  // add the radio button to some view
}

通过这种方式,您不依赖于特定数量的子元素答案,并且您保证不会尝试访问不存在的元素。

如果你真的想根据Answers节点的子节点来做,

Node answersNode = // get the node
NodeList childNodes = answersNode.getChildNodes();
for (int x = 0; x < childNodes.getLength(); x++) {
  Node node = childNodes.get(0);
  if (node instanceof Element && node.getNodeName().equals("answer")) {
    // do the same as above to create a radio button.
  }
}

答案 1 :(得分:0)

使用(简单XML)[http://simple.sourceforge.net/]

@Root
public class Answers {

   @ElementMap(entry="answer", key="value" attribute="true" inline=true)
   public Map<String, String> map;
}

或者如果你只有三个条目,你可以这样做。

@Root
public class Answers {

   @Path("answer[1]")
   @Text
   private answerValue1;

   @Path("answer[2]")
   @Text
   private answerValue2;

   @Path("answer[3]")
   @Text
   private answerValue3;

   @Path("answer[1]")
   @Attribute(name="value")
   private answerAttribute1;

   @Path("answer[2]")
   @Attribute(name="value")
   private answerAttribute2;

   @Path("answer[3]")
   @Attribute(name="value")
   private answerAttribute3;
}

然后如此阅读。

Persister persister = new Persister();
Answers answers = persister.read(Answers.class, xml);

简单!!