从不同的父元素中提取某些XML元素值

时间:2019-03-21 13:32:08

标签: c# xml

我有一个XML文件,其中包含10个Mesh节点,每个节点包含Vertex和Face元素。基本上,对于每个Mesh节点,我需要创建一个:

  • 包含所有顶点(vector3类型)的新列表
  • 包含所有面孔(vector3类型)的新列表
  • 保存网格ID(字符串类型)

对于用于这种动态信息分析和提取的语句,我感到困惑。这是一些简化的XML代码供说明。

<Mesh id="Cube">
  <Vertex position="0.9823, 2.3545, 30.251" />
  <Vertex position="-0.0177, 2.3545, 30.251" />
  <Vertex position="0.9823, 3.3545, 30.251" />
  <Vertex position="-0.0177, 3.3545, 30.251" />
  <Face vertices="0, 2, 3" />
  <Face vertices="0, 3, 1" />

<Mesh id="Wall">
  <Vertex position="-4.9048, -1.0443, -4.8548" />
  <Vertex position="-5.404, -1.018, -4.8636" />
  <Vertex position="-4.6416, 3.9487, -4.8548" />
  <Vertex position="-5.1409, 3.975, -4.8636" />
  <Face vertices="0, 2, 3" />
  <Face vertices="0, 3, 1" />

我当前的解决方案返回“参数超出范围”。我不确定如何将“顶点”列表转换为Vector3列表,以及如何首先获取网格ID。

XDocument xml = XDocument.Load("C:\\Users\\Test.xml");
List<string> Vertices= new List<string>();
int i = 0;

IEnumerable<XElement> de =
    from element in xml.Descendants("Vertex")
    select element;
foreach (XElement element in de)
{
    Vertices[i] = element.Attribute("position").Value;
    i += 1;
}

2 个答案:

答案 0 :(得分:3)

问题是使用列表索引器尝试添加新值。您可以在完全不用担心XML的情况下验证它是否无效:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        var list = new List<string>();
        list[0] = "test"; // Bang: ArgumentOutOfRangeException
    }
}

幸运的是,您根本不需要它-您的代码可以更正并简化为:

XDocument xml = XDocument.Load("C:\\Users\\Test.xml");
List<string> vertices = xml
    .Descendants("Vertex")
    .Select(x => x.Attribute("position").Value)
    .ToList();

答案 1 :(得分:0)

使用Xml Linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication106
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            List<Mesh> mesh = doc.Descendants("Mesh").Select(x => new Mesh()
            {
                id = (string)x.Attribute("id"),
                vertexes = x.Elements("Vertex").Select(y => ((string)y.Attribute("position")).Split(new char[] {','}).Select(z => decimal.Parse(z)).ToList()).ToList(),
                faces = x.Elements("Face").Select(y => ((string)y.Attribute("vertices")).Split(new char[] { ',' }).Select(z => int.Parse(z)).ToList()).ToList(),

            }).ToList();
        }

    }
    public class Mesh
    {
        public string id { get; set; }
        public List<List<decimal>> vertexes { get; set; }
        public List<List<int>> faces { get; set; }


    }


}