【问题标题】:How to Connect 2 Lists如何连接 2 个列表
【发布时间】:2017-01-24 10:17:07
【问题描述】:

我不确定这是否简单。

我有一个结构如下的 XML 文件:

<DEFTABLE>
  <CUBE NAME="FristCube" />
      <OUT NAME="Line1" />
      <OUT NAME="Line2" />
      <IN NAME="LineX" />
      <IN NAME="LineY" />
  </CUBE>
  <CUBE NAME="SecondCube" />
      <OUT NAME="LineX" />
      <OUT NAME="LineY" />
      <IN NAME="Line1" />
      <IN NAME="Line2" />
  </CUBE>
</DEFTABLE>

现在我创建了一个包含所有多维数据集名称的列表、一个包含所有内联的列表和一个包含所有外线的列表。 如您所见,一个 Cube 可以有多个 InLines 和 OutLines - 我怎样才能将它们匹配在一起?

我认为我需要一个包含所有 In- 和 Outlines 的“Cube”类,但我不知道如何实现这一点。

我想创建 CubeList 的 3D 对象(在 Unity 中)并将这些 Cube 与适当的线连接起来。

这就是我将信息放入列表的方式:

private List<Cube> GetCubeList()
{
    XDocument xmlDoc = XDocument.Load (@"Cube_List.xml");
    var cubes = (from c in xmlDoc.Root.Elements("CUBE")
        select new Cube
        {
            Cubename = (string)c.Attribute("NAME"),
            }).ToList();
    return cubes.ToList();

}

  ...

  private List<IN> GetINLines()
{
    XDocument xmlDoc = XDocument.Load (@"Cube_List.xml");
    var inline = (from line in xmlDoc.Root.Elements("CUBE").Descendants("IN")
        select new InLine
        {
            Inline = (string)line.Attribute("NAME").Value,
        }).ToList();
    return inline().ToList();
}

【问题讨论】:

  • 另一种方法是创建一个Line 的类和一个Cube 的类。 Line 类有两个 Cube 元素,InCube 和 OutCube。那么你只需要一个List&lt;Line&gt;

标签: c# xml linq list parsing


【解决方案1】:

创建一个Cube-class 作为傻瓜:

public class Cube
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlArrayItem("In")
    public List<Element> In { get; set; }
    [XmlArrayItem("Out")
    public List<Element> Out { get; set; }
}

public class Element
{
    [XmlAttribute("Name")]
    public string Name { get; set, }
}

最后你需要你周围的DEFTABLE-class:

[XmlRoot("DEFTABLE")]
public class DefTable
{
    [XmlArrayItem("Cube")]
    public List<Cube> Cubes { get; set; }
}

这应该很容易在 Xml 文件中序列化/反序列化:

var ser = new XmlSerializer(typeof(DefTable));
var instance = (DefTable) ser.DeSerialize(myFile);

这种方式比依赖 Linq2Xml 容易得多,因为您可以直接使用之前创建的类结构。

有关序列化的更多信息和示例,请查看MSDN

编辑:从Cube 获取所有In 行现在很容易:

var cube = instance.Cubes.Single(x => x.Name == "FristCube");
var inLines = cube.In;

【讨论】:

  • 这应该可以,但是我认为一个带有“[XMLROOT]”属性和一个多维数据集集合的 DEFTABLE 类会更好。
  • 我等了 3 分钟让您添加缺少的部分,然后添加了我的评论:) 现在大小写的事情可能是个问题,但我同意你的看法;这个解决方案比 Linq2Xml 好
  • 嘿,感谢您的解决方案!我对你最后的“编辑”部分有疑问。 "var cube = defTableInstance.Cubes.Single("FristCube");" ,defTableInstance 不存在,我不知道该插入什么。问候
  • @V.Daymir 我更新了答案,当然我提到了反序列化的实例。
  • @HimBromBeere 啊,谢谢!现在我在使用“Single”编译时遇到错误:System.Collections.Generic.List 没有任何“Single”定义并且存在无效参数。
【解决方案2】:

这是一种方法:

XmlDocument doc = new XmlDocument();
doc.Load(@"Cube_List.xml");
List<XmlNode> allInOutNodes = new List<XmlNode>();

var nodes = doc.SelectNodes("DEFTABLE/CUBE");
foreach (XmlNode node in nodes)
{
    allInOutNodes.AddRange(node.ChildNodes.OfType<XmlNode>());
}

【讨论】:

    【解决方案3】:

    您需要一个两遍算法。第一遍创建立方体、边,并将输入分配给边。第二遍将输出添加到两侧。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication43
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                //pass one create cube and inputs
                foreach(XElement cube in  doc.Descendants("CUBE"))
                {
                    Cube newCube = new Cube();
                    Cube.cubes.Add(newCube);
                    newCube.name = (string)cube.Attribute("NAME");
                    newCube.sides = cube.Elements("IN").Select(y => new Side() {
                        name = (string)y.Attribute("NAME"),
                        _in = newCube
                    }).ToList();
                }
    
                foreach (XElement xCube in doc.Descendants("CUBE"))
                {
                    string outCubeName = (string)xCube.Attribute("NAME");
                    Cube outCube = Cube.cubes.Where(x => x.name == outCubeName).FirstOrDefault();
    
                    foreach(XElement _out in xCube.Elements("OUT"))
                    {
                        string sideName = (string)_out.Attribute("NAME");
                        Boolean found = false;
                        foreach (Cube inCube in Cube.cubes)
                        {
                            foreach (Side side in inCube.sides)
                            {
                                if (side.name == sideName)
                                {
                                    side._out = outCube;
                                    found = true;
                                    break;
                                }
                            }
                            if (found == true) break;
                        }
                    }
                }
    
    
    
            }
        }
        public class Cube
        {
            public static List<Cube> cubes = new List<Cube>();
    
            public string name { get; set; }
            public List<Side> sides { get; set; }
    
        }
        public class Side
        {
            public string name { get; set; }
            public Cube _in { get; set; }
            public Cube _out { get; set; }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2014-05-03
      • 2021-11-02
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      相关资源
      最近更新 更多