我终于完成了我的XML解析代码,现在看着它,它吓到了我。此代码适用于基于Android的简单文本冒险游戏。
我拥有关于存储在'res'文件夹中的XML文件中的遭遇,位置和字符的所有数据。
我编写了这个XML解析器来编写XML文件并将数据存储到一个名为Encounter的类中。然后我可以在我的代码中的任何地方访问Encounter中的数据。
所以我猜我把OOP部分搞定了。但实际的解析看起来很乱。
有没有更好的方法来解析XML数据?
这是我的代码:
public class XmlParser extends Activity {
private String xmlValue;
private int encounterID;
Encounter encounter;
public XmlParser()
throws XmlPullParserException, IOException
{
XmlPullParser xpp = getResources().getXml(R.xml.encounters);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String elName = xpp.getName();
if(eventType == XmlPullParser.START_TAG) { //creature
eventType = xpp.next();
//top level nodes
if(xpp.getName().equalsIgnoreCase("identity")){
eventType = xpp.next();
if(elName.equalsIgnoreCase("name")) {
encounter.name = xpp.getText();
} else if(elName.equalsIgnoreCase("race")) {
encounter.race = xpp.getText();
} else if(elName.equalsIgnoreCase("gender")) {
encounter.gender = xpp.getText();
} else if(elName.equalsIgnoreCase("alignment")) {
encounter.alignment = xpp.getText();
} else if(elName.equalsIgnoreCase("age")) {
try {
encounter.age = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
}
} else if (xpp.getName().equalsIgnoreCase("appearance")) {
eventType = xpp.next();
if(elName.equalsIgnoreCase("condition")){
encounter.condition = xpp.getText();
} else if(elName.equalsIgnoreCase("skinColor")) {
encounter.skinColor = xpp.getText();
} else if(elName.equalsIgnoreCase("hairColor")) {
encounter.hairColor = xpp.getText();
} else if(elName.equalsIgnoreCase("size")) {
encounter.size = xpp.getText();
} else if(elName.equalsIgnoreCase("height")) {
encounter.height = xpp.getText();
} else if(elName.equalsIgnoreCase("weight")) {
encounter.weight = xpp.getText();
}
} else if (xpp.getName().equalsIgnoreCase("stats")) {
eventType = xpp.next();
if(elName.equalsIgnoreCase("hitPoints")) {
try {
encounter.HP = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("armorClass")) {
try {
encounter.AC = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("actionPoints")) {
try {
encounter.AP = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("magicPoint")) {
try {
encounter.AP = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("strength")) {
try {
encounter.strength = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("dexterity")) {
try {
encounter.dexterity = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
} else if(elName.equalsIgnoreCase("intelligence")) {
try {
encounter.intelligence = Integer.parseInt(xpp.getText());
} catch (NumberFormatException e) {
//ok
}
}
} else if (xpp.getName().equalsIgnoreCase("inventory")) {
eventType = xpp.next();
if(elName.equalsIgnoreCase("weapon")) {
encounter.weapon = xpp.getText();
} else if(elName.equalsIgnoreCase("armor")) {
encounter.armor = xpp.getText();
} else if(elName.equalsIgnoreCase("magicItem")) {
encounter.magicItem = xpp.getText();
}
} else if (xpp.getName().equalsIgnoreCase("magic")) {
eventType = xpp.next();
if(elName.equalsIgnoreCase("attackSpell")) {
encounter.attackSpell = xpp.getText();
} else if(elName.equalsIgnoreCase("defenseSpell")) {
encounter.defenseSpell = xpp.getText();
}
} else if (xpp.getName().equalsIgnoreCase("treasureItems")) {
eventType = xpp.next();
if(elName.equalsIgnoreCase("item1")) {
encounter.item1 = xpp.getText();
} else if(elName.equalsIgnoreCase("item2")) {
encounter.item2 = xpp.getText();
}
}
} else if(eventType == XmlPullParser.END_TAG) {
//System.out.println("End tag "+xpp.getName());
}
eventType = xpp.next();
}
//System.out.println("End document");
}
如果有人有兴趣,这是我遇到的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<encounters>
<creature id="1" type="monster">
<identity>
<name></name>
<race></race>
<gender></gender>
<age></age>
<alignment></alignment>
</identity>
<appearance>
<condition></condition>
<skinColor></skinColor>
<hairColor></hairColor>
<size></size>
<height></height>
<weight></weight>
</appearance>
<stats>
<hitPoints></hitPoints>
<armorClass></armorClass>
<actionPoints></actionPoints>
<magicPoints></magicPoints>
<strength></strength>
<dexterity></dexterity>
<intelligence></intelligence>
</stats>
<inventory>
<weapon></weapon>
<armor></armor>
<magicItem></magicItem>
</inventory>
<magic>
<attackSpell></attackSpell>
<defenseSpell></defenseSpell>
</magic>
<treasureItems>
<item1></item1>
<item2></item2>
</treasureItems>
</creature>
答案 0 :(得分:4)
在处理具有直接对象映射的XML时,如在您的情况下,我通常倾向于使用编组技术。现在最标准的是JAXB。但是它会给你的应用程序增加相当多的开销(aprox 9 megs),这在移动应用程序中是不可忽略的。在这种情况下,一个更轻量级的编组API,如simple,可以有一个利基。
答案 1 :(得分:3)
您可以查看VTD-XML,轻量级图书馆可以使用 与android一样优秀(规模越大,但在文件大小方面要大得多) Android还附带SAX-parser。
除此之外,当我使用XmlPullParser时,我通常有一个带有标记名作为键和整数的地图,然后我可以从地图中获取值然后使用一个简单的开关,它会稍微清除代码:
//Before parsing, or if used frequently the map can be put outside the method and reused:
final HashMap<String, Integer> tags = new HashMap<String, Integer>(9, 1);
tags.put("encounters", 0);
tags.put("identity", 1);
tags.put("name", 2);
//And so on...
//in your parse-loop:
int tag = tags.get(xpp.getName());
switch(tag){
case 0: //Handle encounter tag...
break;
case 1: //Handle identity tag...
break;
case 2: //Handle name tag...
break;
//For all tags.
}