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

发布于 2024-11-05 07:53:46 字数 2009 浏览 1 评论 0原文

在我的应用程序中,我正在解析 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???

非常感谢您的帮助!

In my app I'm parsing an xml, piece of structure doing problems:

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

I'm parsing it with XML DOM:

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

that works great and depending on answer items I'm creating a RadioButtons like this:

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);

This piece of code works perfectly in the emulator, SDK v.7 (Android 2.0), while my HTC Desire runs on Android 2.1u1 (so SDK v.8)

But in the device I get error on this line button2.setText(answers.item(2).getChildNodes().item(0).getNodeValue()); guessing that there is no .item(2) in answers - but it has to be... I was debugging this code within emulator and found out that answers.item(0) is a TextNode containing the name of the XML node "answers"...

But it is true I'm a bit confused and everything is messing up when parsing this XML as I still have to count how deep am I and when to call what index on which element (node)... But still I found this implementation much simpler than using SAX...

Isn't there something simillar to SimpleXml from PHP in Java???

Anyway, my main problem is: how is it possible that application is working perfectly in emulator while on device it throws NullPointerException on the line where I try to set text for button2???

Many thanks for You help!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴情 2024-11-12 07:53:46

getChildNodes() 返回答案下的所有 Node,而不仅仅是所有 Element。您可能想要迭代所有子元素,并检查每个子元素是否都是带有标签名称“answer”的 Element

这样怎么样:

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.
  }
}

getChildNodes() returns all Nodes under answers, not just all Elements. You probably want to iterate through all of the children and check if each is an Element with tag name "answer"

How about something like this:

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
}

That way you aren't dependent on a particular number of child elements of answers, and you guarantee you won't try to access one that doesn't exist.

If you really want to do it based on the children of an Answers node,

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.
  }
}
紫轩蝶泪 2024-11-12 07:53:46

使用 (Simple 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);

就这么简单!!

Use (Simple XML)[http://simple.sourceforge.net/]

@Root
public class Answers {

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

Or if you only have three entries you could do.

@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;
}

Then read like so.

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

Simple as that!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文