使用列表C#的属性

时间:2016-12-10 01:51:09

标签: c# xml list loops

这个问题有点儿了。除了三重嵌套List之外,还有一种方法可以向List元素声明属性吗?

上下文: 我有一个PLC列表,其中每个PLC有4个“属性”元素和一个标签列表。

Ex:我知道这是错的,只是想说明这个想法。

List<List<string>> plcTagInfo;
plcTagInfo[0][0] = PLC Name
plcTagInfo[0][1] = IP address of aforementioned PLC
plcTagInfo[0][2] = protocol used to communicate with PLC.
plcTagInfo[0][3] = processor type of aforementioned PLC.
plcTagInfo[0][4] = List of ALL tags inside of that PLC and each tag has 4 elements.
plcTagInfo[1] = new plc to cycle through.

我将遍历每个标记和标记属性。

Tag Elements are: tagName(string), dataType(string = uint32), elemSize(string = "4"), elemCount(string = "10") as an example.

有一条简单的路线可以解决这个问题吗?或者我应该将plc分成一个列表,将标签拆分成一个单独的列表并逐步将它们关联起来?

以防我不够清楚。这是我从中导入数据的XML。

<?xml version="1.0" encoding="utf-8"?>
<PLCS>
  <PLC Name="Test">
    <PLCInfo IPAddress="192.168.1.60" ProcessorType="LGX" Protocol="ab_eip" />
    <Tags>
      <Tag TagName="TagName1" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="TagName2" DataType="uint8" ElemSize="4" ElemCount="1" />
      <Tag TagName="TagName3" DataType="uint8" ElemSize="4" ElemCount="1" />
      <Tag TagName="TagName4" DataType="uint8" ElemSize="4" ElemCount="1" />
      <Tag TagName="TagName5" DataType="uint8" ElemSize="4" ElemCount="1" />
      <Tag TagName="TagName6" DataType="uint8" ElemSize="4" ElemCount="1" />
      <Tag TagName="TagName" DataType="uint8" ElemSize="4" ElemCount="10" />
    </Tags>
  </PLC>
  <PLC Name="Test2">
    <PLCInfo IPAddress="192.168.1.30" ProcessorType="LGX" Protocol="ab_eip" />
    <Tags>
      <Tag TagName="Tagname1" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname2" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname3" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname4" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname5" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname6" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname7" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="Tagname8" DataType="uint8" ElemSize="4" ElemCount="10" />
      <Tag TagName="TagName1" DataType="uint8" ElemSize="4" ElemCount="10" />
    </Tags>
  </PLC>
</PLCS>

MuchosDankeschön!

4 个答案:

答案 0 :(得分:2)

创建一个对象,定义您关心的属性,然后创建该对象的List

答案 1 :(得分:2)

不是将xml解析为列表,而是创建一个与XML对应的类,然后对其进行反序列化。有关示例,请参阅this answer。

答案 2 :(得分:1)

我有一个相当不错的工作流程,当我需要处理XML时效果很好。 Visual Studio内置了一些处理XML的好工具,有些步骤只需要一些按摩来使其正确。

有一点需要注意 - XML必须是可由XSD验证的东西。

如果您已有XML的XSD,则可以跳过步骤1-2)

  1. 通过xsd.exe运行文档。您可以通过Visual Studio的Developer Command Prompt运行此工具。 (通常位置位于开始菜单中的Visual Studio文件夹中。此命令的典型执行是xsd.exe MyXMLFile.xml。输出将是文件MyXMLFIle.xsd
  2. 按摩XSD文件。对于XML,它生成了一个允许存在多个<Tags /><PLCInfo />元素的模式,我认为这是不正确的,因此我适当地调整了模式。

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema id="PLCS" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
      <xs:element name="PLCS" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="PLC">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="PLCInfo" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                      <xs:attribute name="IPAddress" type="xs:string" />
                      <xs:attribute name="ProcessorType" type="xs:string" />
                      <xs:attribute name="Protocol" type="xs:string" />
                    </xs:complexType>
                  </xs:element>
                  <xs:element name="Tags" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element name="Tag" minOccurs="0" maxOccurs="unbounded">
                          <xs:complexType>
                            <xs:attribute name="TagName" type="xs:string" />
                            <xs:attribute name="DataType" type="xs:string" />
                            <xs:attribute name="ElemSize" type="xs:string" />
                            <xs:attribute name="ElemCount" type="xs:string" />
                          </xs:complexType>
                        </xs:element>
                      </xs:sequence>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
                <xs:attribute name="Name" type="xs:string" />
              </xs:complexType>
            </xs:element>
          </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    
  3. 再次通过xsd.exe运行xsd文件,这次指定生成代码。典型执行是xsd.exe MyXMLFile.xsd /c /n:Example.Model。输出将是C#源代码文件MyXMLFile.xs。

  4. 将生成的.cs文件添加到项目中。
  5. 为XML的根类型实例化XMLSerializer。在您的文档案例中,这是PLCS。在下面的示例中,我将XML作为一个字符串传递给StringReader以提供Deserialize()方法。

    using Example.Model;
    
    // ... later
    
    XmlSerializer serializer = new XmlSerializer(typeof(PLCS), new XmlRootAttribute{ ElementName = "PLCS" });
    var reader = new StringReader(textXml);
    PLCS info = (PLCS) serializer.Deserialize(reader);
    
  6. 从那里开始,就像任何其他POCO一样。这是把它输出到控制台的东西。

    foreach (var plc in info.Items)
    {
        Console.WriteLine(plc.Name);
        Console.Write($"{plc.PLCInfo.IPAddress} {plc.PLCInfo.ProcessorType} {plc.PLCInfo.Protocol}\r\n");
        foreach (var tag in plc.Tags)
        {
            Console.WriteLine($"\t[{tag.TagName}] {tag.DataType} {tag.ElemSize} {tag.ElemCount}");
        }
    }
    

答案 3 :(得分:0)

使用xml linq

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var results = doc.Descendants("PLC").Select(x => new {
                name = (string)x.Attribute("Name"),
                ipAddress = (string)x.Element("PLCInfo").Attribute("IPAddress"),
                tags = x.Descendants("Tag").Select(y => new {
                        name = (string)y.Attribute("TagName"),
                        type = (string)y.Attribute("DataType"),
                        size = (int)y.Attribute("ElemSize"),
                        count = (int)y.Attribute("ElemCount")
                }).ToList()
            }).ToList();

        }
    }
}