2016-03-04 178 views
2

我試圖從xml文件中讀取並不總是相同的模式,目標是從文件中讀取數據並將收集的數據排序爲數組,然後我可以使用了例如排序的數據...C#XML閱讀器試圖從XML文件中讀取

XML文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<imgdir name="Eqp.img"> 
    <imgdir name="Eqp"> 
     <imgdir name="Accessory"> 
      <imgdir name="1010000"> 
       <string name="name" value="Long Brown Beard"/> 
      </imgdir> 
      <imgdir name="1010001"> 
       <string name="name" value="Goatee"/> 
      </imgdir> 
      <imgdir name="1010002"> 
       <string name="name" value="Ninja Mask for Men"/> 
      </imgdir> 
      <imgdir name="1010003"> 
       <string name="name" value="5 O'Clock Shadow"/> 
      </imgdir> 
      <imgdir name="1010004"> 
       <string name="name" value="General's Mustache (1)"/> 
      </imgdir> 
      <imgdir name="1010005"> 
       <string name="name" value="General's Mustache (2)"/> 
      </imgdir> 
      </imgdir> 
     <imgdir name="Face"> 
      <imgdir name="1010006"> 
       <string name="name" value="Yakuza Scar"/> 
      </imgdir> 
      <imgdir name="1011000"> 
       <string name="name" value="Ninja Mask for Women"/> 
      </imgdir> 
      <imgdir name="1011001"> 
       <string name="name" value="SF Ninja Mask"/> 
      </imgdir> 
      </imgdir> 

這是我的代碼

Uri uri = new Uri(path); 
string filename = System.IO.Path.GetFileName(uri.LocalPath); 
XmlReader reader = XmlReader.Create(path); 
int x = 0; 
int Row_length = 0; 
#region Check Rows Length in File 
//=================================================================================================== 
XmlDocument doc = new XmlDocument(); 
doc.Load(path); 
XmlElement root = doc.DocumentElement; 
XmlNodeList elemList = root.GetElementsByTagName("imgdir"); 
for (x = 0; x < elemList.Count; x++) ; 
DisplayChanges_Box.Text += ("Total Elements Count= " + x + '\n' + "XML File= " + filename + '\n'); 
Row_length = x; 

#endregion 
int CurrentArrayDataBox = 0; 
int[] itemIDArray = new int[x + 1]; 
string[] itemNamesArray = new string[x + 1]; 
int LastRow = Row_length; 

while (reader.Read()) 
{ 
    if (reader.IsStartElement()) 
    { 
     if (reader.HasAttributes) 
     { 
      // <<Checking if the current elemnt is a number or Group Name such as Weapons...Gloves...etc>> 
      string ItemNumberAsString; 
      int ItemNumber; 
      string ItemDescription; 
      ItemNumberAsString = reader.GetAttribute("name"); 
      bool parsed = Int32.TryParse(ItemNumberAsString, out ItemNumber); 
      if (parsed) 
      { 
       reader.ReadToNextSibling("string"); 
       ItemDescription = reader.GetAttribute("string"); 
       // <<Write To ID and Names Array the gained data values>> 
       itemIDArray[CurrentArrayDataBox] = ItemNumber; 
       itemNamesArray[CurrentArrayDataBox] = ItemDescription; 
       CurrentArrayDataBox++; 
       reader.ReadToFollowing("imgdir"); 
      } 
      else if (!parsed) 
      { 
       reader.ReadToFollowing("imgdir"); 
      } 
     } 
    } 
} 

=========== =====
Th C計劃是應該有點像這樣的信息...
每次它會檢查當前的屬性來檢測,如果它是一個字符串,如時間:

"Eqp.img" 
"Eqp" 
"Accessory" 

忽略它們
或者如果它是

"1010000" 
"1010001" 
"1010002" 
"1010003" 
... 

將數字存儲在ItemIDArray和他們的字符串名稱值存儲在ItemNamesArray

目前我似乎無法獲得數字只檢測如果它我是字符串,雖然屬性是數字,但它顯示爲「名稱」,而不是實數

此致敬禮。

+0

你爲什麼用XmlReader *和*將整個事件讀入XmlDocument? (我鼓勵你一般使用LINQ to XML - 它是一個*更好的XML API。) –

+0

我通常會盡量避免使用XmlReader,除非你確實需要它。 LINQ to XML在這裏可能會簡單得多。但問題並不清楚,特別是「它表明它」並不能解釋*什麼顯示什麼。 –

+0

當它讀取數值而不是顯示數字,而調試它顯示值爲「名稱」,以及關於linq ..以及我只是用於XMLreader – Extzy

回答

0

以下代碼檢查imgdir節點是否有字符串子節點。

private bool ReadNameAndValue(XmlNode parent, out string name, out string value) 
{ 
    name = ""; 
    value = ""; 

    var node = parent.SelectSingleNode("./string"); 
    if (node == null) 
    { 
     return false; 
    } 

    try 
    { 
     name = parent.SelectSingleNode("./string/@name").InnerText; 
     value = parent.SelectSingleNode("./string/@value").InnerText; 
    } 
    catch(Exception) 
    { 
    } 

    return true; 
} 

public void ParseDoc(string fileName = @"c:\temp\soexample.xml") 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(fileName); 

    var elements = doc.SelectNodes("//imgdir"); 

    foreach (XmlNode node in elements) 
    { 
     string name; 
     string value; 
     if (ReadNameAndValue(node, out name, out value)) 
     { 
      string id = node.SelectSingleNode("./@name").InnerText; 
      Console.WriteLine("Id: " + id + ", Name: " + name + ", Value: " + value); 

      //do whatever you want with the id, name and value 
     } 
    } 
} 

這樣做的打印輸出

Id: 1010000, Name: name, Value: Long Brown Beard 
Id: 1010001, Name: name, Value: Goatee 
Id: 1010002, Name: name, Value: Ninja Mask for Men 
Id: 1010003, Name: name, Value: 5 O'Clock Shadow 
Id: 1010004, Name: name, Value: General's Mustache (1) 
Id: 1010005, Name: name, Value: General's Mustache (2) 
Id: 1010006, Name: name, Value: Yakuza Scar 
Id: 1011000, Name: name, Value: Ninja Mask for Women 
Id: 1011001, Name: name, Value: SF Ninja Mask 
+0

謝謝你alot!幫助 – Extzy

0

正如喬恩暗示,LINQ到XML是簡單得多這裏,很多更具可讀性。這是你可以接近的一種方式:

var doc = XDocument.Load(path); 

var items = from imgdir in doc.Descendants("imgdir") 
      let name = (string)imgdir.Attribute("name") 
      from id in TryParseInteger(name) 
      from description in imgdir.Elements("string").Attributes("value").Take(1) 
      select new {Id = id, Description = description.Value}; 

TryParseInteger是像這樣實現的:

private static IEnumerable<int> TryParseInteger(string value) 
{ 
    int result; 

    if (int.TryParse(value, out result)) 
    { 
     yield return result; 
    } 
} 

this fiddle的工作示例。