C#循环遍历XML节点

13

我正在将二维坐标保存在一个类似于以下结构的XML文件中:

<?xml version="1.0" encoding="utf-8" ?> 
<grid>
<coordinate time="78">
<initial>540:672</initial> 
<final>540:672</final> 
</coordinate>
</grid>
我可以使用XmlTextReader打开XML文件并读取它,但是我该如何循环遍历坐标,以便检索初始节点和结束节点之间的时间属性和数据,并以某种类似于以下格式的方式返回:
string initial = "540:672";
string final  = "540:672";
int time = 78;

新代码:

我的新代码:

//Read the XML file.
XDocument xmlDoc = XDocument.Load("C:\\test.xml");

foreach (var coordinate in xmlDoc.Descendants("coordinate"))
{
    this.coordinates[this.counter][0] = coordinate.Attribute("time").Value;
    this.coordinates[this.counter][1] = coordinate.Element("initial").Value;
    this.coordinates[this.counter][2] = coordinate.Element("final").Value;
    this.counter++;
};

但现在我遇到了这个错误:
"对象引用未设置为对象的实例。"


XML

<?xml version="1.0" encoding="utf-8"?>
<grid>
  <coordinate time="62">
    <initial>540:672</initial>
    <final>540:672</final>
  </coordinate>

  ...

  <coordinate time="46">
    <initial>176:605</initial>
    <final>181:617</final>
  </coordinate>
</grid>

省略了一些坐标标签以适应,但它们都有时间属性和初始/最终子标记。


全局变量

uint counter = 0;

        // Coordinates to be retrieved from the XML file.
        string[][] coordinates;

@Gio:请查看我回答中的更新。 - marc_s
2个回答

29

你可能想要了解类似于 Linq-to-XML 的东西:

XDocument coordinates = XDocument.Load("yourfilename.xml");

foreach(var coordinate in coordinates.Descendants("coordinate"))
{
    string time = coordinate.Attribute("time").Value;

    string initial = coordinate.Element("initial").Value;
    string final = coordinate.Element("final").Value;

    // do whatever you want to do with those items of information now
}

使用 LINQ-to-XML 应该比直接使用低级的 XmlTextReader 更容易。查看 这里 或者 这里(或许还有其他很多地方)来了解 LINQ-to-XML 的介绍。


更新:

请尝试以下代码,如果它能够工作并且您可以在结果列表中获得所有坐标,则说明 LINQ-to-XML 代码没有问题:

定义一个新的辅助类:

public class Coordinate
{
    public string Time { get; set; }
    public string Initial { get; set; }
    public string Final { get; set; }
}

并且在你的主要代码中:

XDocument xdoc = XDocument.Load("C:\\test.xml");
IEnumerable<XElement> cords= xdoc.Descendants("coordinate");

var coordinates = cords
                  .Select(x => new Coordinate()
                                   {
                                      Time = x.Attribute("time").Value,
                                      Initial = x.Element("initial").Value,
                                      Final = x.Element("final").Value
                                    });

这个列表及其内容是什么样子?你能得到所有你期望的坐标吗?


3
赞同。我现在尽可能使用XDocument / XElement,因为它更加容易。 - womp
1
@Gio:using System.Xml.Linq; 在 .NET 3.5 及以上版本可用。 - marc_s
我有它,只是忘记引用了。谢谢大家。 - Gio Borje
"对象引用未将对象实例化。" 还需要帮忙吗? - Gio Borje
如果你需要解析小型XML文件,那么使用XDocument是完全可以的。 - Spence

0
您可以使用XmlSerialization将XML转换为一个简单的坐标类列表,只需要少量的工作,例如:
    public class coordinate
    {
        [XmlAttribute]
        public int time;
        [XmlElement(ElementName="initial")]
        public string initial;
        [XmlElement(ElementName = "final")]
        public string final;

        public coordinate()
        {
            time = 0;
            initial = "";
            final = "";
        }
    }

    public class grid
    {
        [XmlElement(ElementName="coordinate", Type = typeof(coordinate))]
        public coordinate[] list;

        public grid()
        {
            list = new coordinate[0];
        }
    }     

然后在你的代码中:

XmlReader r = new XmlReader.Create(...);
grid g = (grid) new XmlSerializer(typeof(grid)).Deserialize(r);

我正在考虑这个问题,但我以前从未做过序列化。 - Gio Borje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接