建议简化加载XML文件的代码?

时间:2011-12-21 14:57:14

标签: java android xml refactoring

我终于完成了我的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>

2 个答案:

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