2016-08-23 67 views
1

我的朋友寫了這段XML代碼,在我們的遊戲簡單的測試,當談到加載和寫入保存數據。問題是他的代碼根本不起作用,而且我從未寫過任何XML代碼,所以這對我來說是新的,我決定學習XML。 所有它想要的是x和y值來創建一個新的Tile對象。 當運行代碼它給出了錯誤:GetElementByID.GetElementsByTagName返回null

System.NullReferenceException了未處理

的HResult = -2147467261

消息=對象不設置爲一個對象的一個​​實例參考。

TL; DR它加載簡單的瓷磚和所有它尋找的是x和y位置以後添加到在水平類訪問列表。

的代碼,他寫道:如下圖所示

<tiles> 
<tile> 
    <position x="10" y="20" /> 
</tile> 
<tile> 
    <position x="50" y="20" /> 
</tile> 
<tile> 
    <position x="30" y="40" /> 
</tile> 
</tiles> 

public class XmlHandler 
{ 
    private List<Base.Tile> tiles; 
    public XmlHandler() 
    { 
    } 
    public void Load() 
    { 
     XmlDocument documentFile = new XmlDocument(); 
     documentFile.Load(@"C:\Tiles\0.xml"); 

     var listOfTiles = documentFile.GetElementById("tiles").GetElementsByTagName("tile"); 

     foreach(XmlElement tile in listOfTiles) 
     { 
      var x = ((XmlElement)tile.GetElementsByTagName("position")[0]).GetAttribute("x"); 
      var y = ((XmlElement)tile.GetElementsByTagName("position")[0]).GetAttribute("y"); 
      Classes.Base.Tile t = new Base.Tile(new Vector2(float.Parse(x), float.Parse(y))); 
      this.tiles.Add(t); 
     } 
    } 
    public List<Base.Tile> GetTiles() 
    { 
     return this.tiles; 
    } 
} 

目前的XML文件,從原來的修改,這是原始的XML,我修改,因爲第一線造成的錯誤

<?xml encoding="utf-8"?> 
<tiles> 
<tile> 
    <id>1</id> 
    <position x="10" y="20" /> 
</tile> 
<tile> 
    <id>2</id> 
    <position x="50" y="20" /> 
</tile> 
<tile> 
    <id>3</id> 
    <position x="30" y="40" /> 
</tile> 
</tiles> 

感謝您的觀看/閱讀。任何幫助表示讚賞!

回答

2

的錯誤是在這裏:

var listOfTiles = documentFile.GetElementById("tiles").GetElementsByTagName("tile"); 

變化這樣說:

var listOfTiles = documentFile.GetElementsByTagName("tiles").GetElementsByTagName("tile"); 

<tiles>是一個標籤,也沒有有任何標識。

1

我不知道這是否是完整的類或沒有,但首先它看起來像您尚未創建了瓷磚的列表。

某處你開始增加瓷磚列表「磚」之前,你需要寫:

瓦=新名單();

我建議構造。

這也將是有益的知道在哪裏空引用異常發生。確保您的列表已設置,然後如果問題仍然存在,請添加評論,然後我將在我的計算機上運行您的代碼。

+0

斯蒂法諾是正確的,但我會建議使用這種以文件的磚來代替: documentFile.SelectNodes(「//瓷磚「); 這將返回XML文件中稱爲tile的任何位置的XmlNode列表。它可以節省你必須得到瓷磚元素,然後從那裏獲取瓷磚。 –

+0

不可能像這樣創建一個新的NodeList。 – Emily

1

the docsGetElementById將返回具有id元件如在DTD中定義(或只是id默認情況下)屬性。你沒有任何id屬性,所以這返回null - 因此是例外。

如果更改了違規行這樣的:

var listOfTiles = documentFile.GetElementsByTagName("tile"); 

然後你當前的代碼將正常工作。然而...LINQ到XML是一個更乾淨的API,你可以如下寫你的整個方法:

var doc = XDocument.Load(@"C:\Tiles\0.xml"); 

var tiles = 
    from tile in doc.Descendants("tile") 
    from position in tile.Elements("position") 
    let x = (float)position.Attribute("x") 
    let y = (float)position.Attribute("y") 
    select new Base.Tile(new Vector2(x, y)); 

this.tiles = tiles.ToList(); 
+0

這解決了我所有的問題!謝謝。 – Emily