我使用兩個類來使用DOM解析器解析XML文檔。樣本元素「對象」是這樣的:當DOM元素作爲參數傳入構造函數時拋出NullPointer異常
<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()));
}
}
和類描述符內的另一個類用於解析上述目的:
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;
}
}
}
上面的代碼拋出一個空指針異常,當「對象」元素作爲參數傳遞給發送ObjectDesc的構造函數,但是,我可以獲得First Class中的屬性和字段。 JAXB似乎是解析這些文檔的正確選擇,但是我花了2天的時間編寫了這個Horror後發現了它們。 堆棧跟蹤:
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)
NullPointer發生在哪裏?顯示堆棧跟蹤(並標記該行)。 – Kayaman
我在代碼中添加了斷點作爲註釋。 – UserNotFound
我評論過'// NullPointerException拋出這裏'在第二個代碼塊(看近端)。 – UserNotFound