这是我的目标是迭代所有节点而不仅仅是一个节点的代码,因此在我的情况下,它会立即获得第一个设备节点和所有子节点,因此我如何获得每个Device和PortA PortB节点。然后我就可以设置我的班级值了。
private void loadXmlFile(string path)
{
try
{
XElement deviceElement = XElement.Load(path);
Device device = new Device();
var allElements = deviceElement.DescendantNodes();
foreach (var elm in deviceElement.Elements())
{
if (elm.Name == "Device")
{
foreach (XAttribute att in elm.Attributes())
{
if (att.Name == "Type")
{
device.TBType1 = att.Value.ToString();
}
if (att.Name == "Name")
{
device.Name = att.Value.ToString();
}
if (att.Name == "ParentConnectedToPort")
{
device.ParentConnectedTo = att.Value.ToString();
}
if (att.Name == "DeviceConnectedToPort")
{
device.DeviceConnectedTo = att.Value.ToString();
}
string connectedTo = (string)elm.Parent.Attribute("Connected_BY");
if (att.Name == "properties" && connectedTo == "Directly")
{
string str = att.Value;
string[] parts = str.Split(':', ',');
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
这是我的XML文件看起来需要获取每个设备元素及其自己的值并设置为我的类值。
<CMS>
<Device Name="CM_HOST" Type="TR">
<PortA Connected_BY="Directly">
<Device TB="AR" ParentConnectedToPort="A" Name="Akitio" DeviceConnectedToPort="A" properties="{'Type': 'AR' ,'Name': 'Akitio','Cable': '20G Passive'}">
<PortB Connected_BY="Directly">
<Device TB="AR" ParentConnectedToPort="A" Name="doc1" DeviceConnectedToPort="B" properties="{'Type': 'AR' ,'Name': 'doc1','Cable': '20G Passive'}">
<PortB Connected_BY="Directly">
<Device TB="AR" ParentConnectedToPort="A" Name="doc2" DeviceConnectedToPort="B" properties="{'Type': 'AR' ,'Name': 'doc2','Cable': '20G Passive'}" />
</PortB>
<PortA Connected_BY="None" />
<PortE Connected_BY="None" />
</Device>
</PortB>
<PortA Connected_BY="None" />
<PortE Connected_BY="None" />
</Device>
</PortA>
<PortB Connected_BY="None" />
<PortE Connected_BY="None" />
</Device>
<Sx properties="{'FTDI_port': '0' ,'SX_power_button_pin': '7','SX_SLP_S3_pin': '6','SX_SLP_S4_pin': '11','SX_SLP_S5_pin': '10','SX_TBT_wake_N_pin': '8','SX_PCIE_wake_pin': '9','G3_Power_Mode': 'PowerSplitter'}" />
</CMS>
答案 0 :(得分:0)
使用XPath,您可以通过选择路径来选择节点列表。
答案 1 :(得分:0)
Xml序列化可能能够做你想要的。不完全确定你的最终结果是什么。您可以使用下面的类来简单地读取xml数据,然后从结果中创建所需的对象。
创建类。
public class CMS
{
[XmlElement("Device")]
List<Device> Devices {get;set;}
//other properties here...
}
public class Device
{
public Port PortA { get;set;}
public Port PortB { get;set;}
public Port PortC { get;set;}
public Port PortD { get;set;}
public Port PortE { get;set;}
//other properties here...TB, ParentConnectedToPort etc
}
public class Port
{
public Device Device { get; set; }
//other properties here...Connected_BY etc
}
然后您可以使用此函数从字符串反序列化:
public static T DeserializeXml<T>(string str)
{
var serializer = new XmlSerializer(typeof(T));
object result;
using (TextReader reader = new StringReader(str))
{
result = serializer.Deserialize(reader);
}
return (T) result;
}
因此使用:
var s = "--your xml string--";
var obj = Deserialize<CMS>(s);
然后,obj将成为xml数据中一个完全填充的对象。如果这是你想要的东西我可以填补上面的空白。
答案 2 :(得分:0)
我喜欢使用递归算法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApplication13
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement cms = doc.Descendants("CMS").FirstOrDefault();
XElement device = cms.Element("Device");
Device.RecursiveParseXml(device, Device.root);
}
}
public class Device
{
public static Device root = new Device();
public List<Port> ports { get; set; }
public string name { get; set; }
public string type { get; set; }
public string tb { get; set; }
public string deviceConnectedToPort { get; set; }
public Dictionary<string, string> properties { get; set; }
public static void RecursiveParseXml(XElement parent, Device device)
{
device.name = (string)parent.Attribute("Name");
device.type = (string)parent.Attribute("Type");
device.tb = (string)parent.Attribute("TB");
device.deviceConnectedToPort = (string)parent.Attribute("DeviceConnectedToPort");
string strProperties = (string)parent.Attribute("properties");
if (strProperties != null)
{
string[] propertyArray = strProperties.Split(new char[] { ',', '{', '}' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
string pattern = @"'(?'name'[^']+)':\s+'(?'value'[^']+)";
device.properties = new Dictionary<string, string>();
foreach (string property in propertyArray)
{
Match match = Regex.Match(property, pattern);
device.properties.Add(match.Groups["name"].Value, match.Groups["value"].Value);
}
}
foreach (XElement element in parent.Elements())
{
Port newPort = new Port();
if (device.ports == null)
{
device.ports = new List<Port>();
}
device.ports.Add(newPort);
newPort.connectBy = (string)element.Attribute("Connected_BY");
XElement newDevice = element.Element("Device");
if (newDevice != null)
{
newPort.device = new Device();
RecursiveParseXml(element.Element("Device"), newPort.device);
}
}
}
}
public class Port
{
public string name { get; set; }
public string connectBy { get; set; }
public Device device { get; set; }
}
}