当元素作为参数传递给构造函数时,DOM元素抛出NullPointer异常

时间:2013-08-17 12:40:02

标签: java dom xml-parsing

我正在使用两个类来使用DOM解析器解析XML文档。示例元素“Object”如下所示:

<Object type="0x632" id="Fire Golem">
    <Group>Golems</Group>
    <Enemy/>
    <Class>Character</Class>
    <AnimatedTexture><File>chars8x8rMid</File><Index>0x0e</Index></AnimatedTexture>
    <HitSound>monster/golems_hit</HitSound>
    <DeathSound>monster/golems_death</DeathSound>
    <Size>140</Size>
    <MaxHitPoints>220</MaxHitPoints>
    <Defense>3</Defense>
    <Terrain>MidSand</Terrain>
    <XpMult>0.7</XpMult>
    <SpawnProb>1.0</SpawnProb>

    <Projectile id="0">
        <ObjectId>Red Fire</ObjectId>
        <Damage>35</Damage>
        <Speed>45</Speed>
        <LifetimeMS>4500</LifetimeMS>
        <Size>100</Size>
    </Projectile>
    <Projectile id="1">
        <ObjectId>Red Fire</ObjectId>
        <Damage>45</Damage>
        <Speed>60</Speed>
        <LifetimeMS>2500</LifetimeMS>
        <Size>220</Size>
    </Projectile>


</Object>

我正在使用2个类来解析XML,一个用于获取这样的元素,另一个用于解析这些元素。

eList = root.getElementsByTagName("Object");
        for(int i = 0, len = eList.getLength();i<len;i++){
            Element elem = (Element)eList.item(i);
            Element sub=(Element)elem.getElementsByTagName("Class").item(0);

            //Doesn't Contain Element 'Class'? No Entry!
            if(sub.equals(null))
                continue;

            //Get Object Attributes
            String Class = sub.getTextContent();
            short type = (short)Util.getInt(elem.getAttribute("type"));
            String id = elem.getAttribute("id");
            System.out.println(Class+" "+type+" "+id);
            //Categorizing
            //Sellable
            if(Class.equalsIgnoreCase("Equipment")||Class.equalsIgnoreCase("Dye")||Class.equalsIgnoreCase("Pet")){
                ItemDescs.put(type, Desc.new Item(elem));
                //Set Up Shop Locations and Prices
                if((sub = (Element)elem.getElementsByTagName("Shop").item(0))!=null){
                    ItemShops.put((int)type, sub.getElementsByTagName("Name").item(0).getTextContent());
                    ItemPrices.put(type, Util.getInt(sub.getElementsByTagName("Price").item(0).getTextContent()));
                }
            }

            //Game Pieces
            if(Class.equalsIgnoreCase("Character")||Class.equalsIgnoreCase("GameObject")||Class.equalsIgnoreCase("Wall")||
                    Class.equalsIgnoreCase("ConnectedWall")||Class.equalsIgnoreCase("CaveWall")||Class.equalsIgnoreCase("Portal")){
                Descriptors.ObjectDesc Piece = Desc.new ObjectDesc(elem); //NullPointerException Thrown Here
                ObjectDescs.put(type, Piece);
            }


            //Portals
            if(Class.equalsIgnoreCase("Portal")){
                PortalDescs.put(type, Desc.new PortalDesc(elem));
            }

            //Keys
            if((sub = (Element)elem.getElementsByTagName("Key").item(0))!=null){
                Keys.add(type);
                KeyPrices.put(type, Util.getInt(sub.getTextContent()));
            }
        }

类Descriptor中的另一个类用于解析上面的Object:

    class Descriptors{
      public class ObjectDesc{
    public short ObjectType;
    public String ObjectId;
    public String DisplayId;
    public String Group;
    public String Class;
    public boolean Player;
    public boolean Enemy;
    public boolean OccupySquare;
    public boolean FullOccupy;
    public boolean EnemyOccupySquare ;
    public boolean Static;
    public boolean NoMiniMap ;
    public boolean ProtectFromGroundDamage;
    public boolean ProtectFromSink;
    public boolean Flying;
    public boolean ShowName;
    public boolean DontFaceAttacks;
    public int MinSize;
    public int MaxSize;
    public int SizeStep;
    public ProjectileDesc[] Projectiles;

    public int MaxHP;
    public int Defense;
    public String Terrain;
    public float SpawnProbability;
    public SpawnCount Spawn;
    public boolean Cube;
    public boolean God;
    public boolean Quest ;
    public int Level;
    public boolean StasisImmune;
    public boolean Oryx ;
    public boolean Hero ;
    public Integer PerRealmMax ;
    public Float ExpMultiplier ;    //Exp gained = level total / 10 * multi

    public ObjectDesc(Element elem){
        Element sub;
        ObjectType = (short)Util.getInt(elem.getAttribute("type"));
        ObjectId = elem.getAttribute("id");
        Class = elem.getElementsByTagName("Class").item(0).getTextContent();
        if((sub =(Element)elem.getElementsByTagName("Group").item(0))!=null)
            Group = sub.getTextContent();
        else
            Group = null;
        if((sub = (Element)elem.getElementsByTagName("DisplayId").item(0))!=null)
            DisplayId = sub.getTextContent();
        else
            DisplayId = null;

        Player = elem.getElementsByTagName("Player").getLength()!=0;
        Enemy = elem.getElementsByTagName("Enemy").getLength()!=0;
        OccupySquare = elem.getElementsByTagName("OccupySquare").getLength()!=0;
        FullOccupy = elem.getElementsByTagName("FullOccupy").getLength()!=0;
        EnemyOccupySquare = elem.getElementsByTagName("EnemyOccupySquare").getLength()!=0;
        Static = elem.getElementsByTagName("Static").getLength()!=0;
        NoMiniMap = elem.getElementsByTagName("NoMiniMap").getLength()!=0;
        ProtectFromGroundDamage = elem.getElementsByTagName("ProtectFromGroundDamage").getLength()!=0;
        ProtectFromSink = elem.getElementsByTagName("ProtectFromSink").getLength()!=0;
        Flying = elem.getElementsByTagName("Flying").getLength()!=0;
        ShowName = elem.getElementsByTagName("ShowName").getLength()!=0;
        DontFaceAttacks = elem.getElementsByTagName("DontFaceAttacks").getLength()!=0;

        if ((sub = (Element)elem.getElementsByTagName("Size").item(0)) != null)
        {
            MinSize = MaxSize = Util.getInt(sub.getTextContent());
            SizeStep = 0;
        }
        else
        {
            if ((sub = (Element)elem.getElementsByTagName("MinSize").item(0)) != null)
                MinSize = Util.getInt(sub.getTextContent());
            else
                MinSize = 100;
            if ((sub = (Element)elem.getElementsByTagName("MaxSize").item(0)) != null)
                MaxSize = Util.getInt(sub.getTextContent());
            else
                MaxSize = 100;
            if ((sub = (Element)elem.getElementsByTagName("SizeStep").item(0)) != null)
                SizeStep = Util.getInt(sub.getTextContent());
            else
                SizeStep = 0;
        }

        List<ProjectileDesc> prj = new ArrayList<ProjectileDesc>();
        NodeList nSub;
        nSub=elem.getElementsByTagName("Projectile");
        for(int i=0;i<nSub.getLength();i++){
            prj.add(new ProjectileDesc((Element)nSub.item(i)));
        }
        Projectiles = (ProjectileDesc[])prj.toArray();

    if((sub = (Element)elem.getElementsByTagName("MaxHitPoints").item(0)) != null)
        MaxHP = Util.getInt(sub.getTextContent());
    if ((sub = (Element)elem.getElementsByTagName("Defense").item(0)) != null)
        Defense = Util.getInt(sub.getTextContent());
    if ((sub = (Element)elem.getElementsByTagName("Terrain").item(0)) != null)
        Terrain = sub.getTextContent();
    if ((sub = (Element)elem.getElementsByTagName("SpawnProbability").item(0)) != null)
        SpawnProbability = Float.parseFloat(sub.getTextContent());
    if ((sub = (Element)elem.getElementsByTagName("Spawn").item(0)) != null)
        Spawn = new SpawnCount(sub);

    StasisImmune = elem.getElementsByTagName("StasisImmune").getLength() !=0;
    Oryx = elem.getElementsByTagName("Oryx").getLength() !=0;
    Hero = elem.getElementsByTagName("Hero").getLength() !=0;

    if ((sub = (Element)elem.getElementsByTagName("PerRealmMax").item(0)) != null)
        PerRealmMax = Util.getInt(sub.getTextContent());
    else
        PerRealmMax = null;

    if ((sub = (Element)elem.getElementsByTagName("XpMult").item(0)) != null)
        ExpMultiplier = Float.parseFloat(sub.getTextContent());
    else
        ExpMultiplier = null;

    }       
}
  }

当'Object'元素作为参数发送到ObjectDesc的构造函数时,上面的代码抛出NullPointer异常,但是,我可以获得First Class中的Attributes和Fields。 JAXB似乎是解析这些文档的正确选择,但是在我花了2天编写这个恐怖片之后我发现了它们。 堆栈跟踪:

java.lang.NullPointerException
at com.azuro.ultraserve.db.data.XMLData.ProcessXml(XMLData.java:150)
at com.azuro.ultraserve.db.data.XMLData.ReadXMLs(XMLData.java:69)
at com.azuro.ultraserve.db.data.XMLData.<clinit>(XMLData.java:59)

1 个答案:

答案 0 :(得分:0)

       if(sub.equals(null))
            continue;

不是检查null的方法。如果sub为null,则此代码将抛出NullPointerException。

你想要的是

       if(sub == null)
            continue;

现在我看到你的NullPointerException正在发生哪一行,这可能不是你所看到的问题的原因。导致NullPointerException的行是:

           Descriptors.ObjectDesc Piece = Desc.new ObjectDesc(elem); 

这很可能意味着您的Desc变量为空而不是实际的Descriptors对象。由于ObjectDesc是Descriptors的非静态内部类,因此您需要这样的对象才能调用内部构造函数。