C#XML读取器试图从XML文件中读取

时间:2016-03-04 12:01:37

标签: 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");
            }
        }
    }
}

=====
该程序应该对这样的信息进行排序......
每次检查当前属性以检测它是否为字符串Like:

"Eqp.img"
"Eqp"
"Accessory"

忽略他们 或者如果是

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

将数字存储在ItemIDArray及其字符串名称值中,以存储在ItemNamesArray中

目前我似乎无法获取数字只检测它是否是一个字符串,而属性是数字它显示为“名称”而不是实数

真诚的。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

正如Jon所说,LINQ to 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