这个问题有点儿了。除了三重嵌套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!
答案 0 :(得分:2)
创建一个对象,定义您关心的属性,然后创建该对象的List
。
答案 1 :(得分:2)
不是将xml解析为列表,而是创建一个与XML对应的类,然后对其进行反序列化。有关示例,请参阅this answer。
答案 2 :(得分:1)
我有一个相当不错的工作流程,当我需要处理XML时效果很好。 Visual Studio内置了一些处理XML的好工具,有些步骤只需要一些按摩来使其正确。
有一点需要注意 - XML必须是可由XSD验证的东西。
如果您已有XML的XSD,则可以跳过步骤1-2)
xsd.exe MyXMLFile.xml
。输出将是文件MyXMLFIle.xsd
按摩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>
再次通过xsd.exe
运行xsd文件,这次指定生成代码。典型执行是xsd.exe MyXMLFile.xsd /c /n:Example.Model
。输出将是C#源代码文件MyXMLFile.xs。
为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);
从那里开始,就像任何其他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();
}
}
}