C# 检索多个节点的元素属性
我最难弄明白这一点,我有一个XML文档,它有多个同名节点。在这些节点中,甚至有更多具有相同名称但不同属性的节点,这就是我想要捕获的。以下是XML的一个示例:C# 检索多个节点的元素属性,c#,xml-parsing,C#,Xml Parsing,我最难弄明白这一点,我有一个XML文档,它有多个同名节点。在这些节点中,甚至有更多具有相同名称但不同属性的节点,这就是我想要捕获的。以下是XML的一个示例: <?xml version="1.0" encoding="utf-8"?> <TopologyDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmln
<?xml version="1.0" encoding="utf-8"?>
<TopologyDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/online/managementsystems/topologydefinition/2009/11">
<Topology Name="testenv">
<DataCenters>
<DataCenter Name="FL" Type="Active">
<Machines>
<Machine Name="FLVMServer1" VmHost="FLVHost100">
<IPBindings>
<IPBinding VirtualNetworkType="Data" IP="192.168.0.10" />
</IPBindings>
</Machine>
<Machine Name="FLVMServer2" VmHost="FLVHost200">
<IPBindings>
<IPBinding VirtualNetworkType="Data" IP="192.168.0.20" />
</IPBindings>
</Machine>
</DataCenter>
<DataCenter Name="RI" Type="Passive">
<Machines>
<Machine Name="RIVMServer1" VmHost="RIVHost100">
<IPBindings>
<IPBinding VirtualNetworkType="Data" IP="192.168.2.10" />
</IPBindings>
</Machine>
<Machine Name="RIVMServer2" VmHost="RIVHost200">
<IPBindings>
<IPBinding VirtualNetworkType="Data" IP="192.168.2.20" />
</IPBindings>
</Machine>
</DataCenter>
</DataCenters>
</Topology>
</TopologyDefinition>
我需要为所有DC捕获以下内容:
机器名
虚拟主机
知识产权
我尝试过XPATH,也尝试过遍历每个节点,但没有成功
ServerInfoClass serverInfo = new ServerInfoClass();
XmlDocument doc = new XmlDocument();
doc.Load(FilePath);
XmlNodeList dcElemList = doc.GetElementsByTagName("DataCenter");
for(int j = 0; j < dcElemList.Count; j++)
{
XmlNodeList elemList = doc.GetElementsByTagName("Machine");
for (int i = 0; i < elemList.Count; i++)
{
serverInfo.ServerName = elemList[i].Attributes["Name"].Value;
serverInfo.VmHost = elemList[i].Attributes["VmHost"].Value;
XmlNodeList ipList = doc.GetElementsByTagName("IPBindings");
for (int x = 0; x < ipList.Count; x++) ;
{
//serverInfo.IPAddress = ipList[x].Attributes["IP"].Value;
}
OutPut(serverInfo.ServerName, serverInfo.VmHost, serverInfo.IPAddress);
}
}
ServerInfoClass serverInfo=newserverinfoclass();
XmlDocument doc=新的XmlDocument();
文档加载(文件路径);
XmlNodeList dcElemList=doc.GetElementsByTagName(“数据中心”);
对于(int j=0;j
如果您将其放入XDocument中,您可以这样查询它:
XDocument document = // ... your document.
var ns = document.Root.Name.Namespace;
var results = from dcNode in document.Descendants(ns + "DataCenter")
let Name = dcNode.Attribute("Name").Value
let Type = dcNode.Attribute("Type").Value
let Machines = dcNode.Descendants(ns + "Machine").Select(mNode =>
new {
Name = mNode.Attribute("Name").Value,
VmHost = mNode.Attribute("VmHost").Value,
Bindings = mNode.Descendants(ns + "IPBinding").Attributes("IP").Select(x => x.Value).ToArray()
})
select new { Name, Type, Machines };
我建议创建一个用于获取属性值的助手扩展方法,该方法还检查空值
这里的关键之一是要记住,XML元素位于名称空间中,在查询时需要提供完整的名称空间。这就是为什么首先从根节点提取
ns
名称空间实例非常方便的原因。您的示例格式不太好。您缺少
标记
另一种方法是使用LINQ to XML:
XNamespace ns = "http://schemas.microsoft.com/online/managementsystems/topologydefinition/2009/11";
foreach (var machine in XElement.Load(@"c:\mydata.xml").Descendants(ns + "Machine"))
{
string name = machine.Attribute("Name").Value;
string vmHost = machine.Attribute("VmHost").Value;
XElement ipBinding = machine.Descendants(ns + "IPBinding").Single();
string vnType = ipBinding.Attribute("VirtualNetworkType").Value;
string ip = ipBinding.Attribute("IP").Value;
}
I get序列在XElement ipBinding=machine.substands(ns+“ipBinding”).Single()上包含多个元素;这是使用FirstOrDefault()解决的,而不是关于如何处理null的任何建议?我选择Single()作为示例,因为它与您的示例相匹配。只要第一个是正确的,FirstOrDefault()就可以。如果有多个IP绑定元素,您必须考虑如何处理空缺省值,以及选择正确的默认值。在尝试使用元素或属性之前,必须对空进行测试。如果需要一个元素,那么您现在可以抛出一个异常。为什么这不会在两个数据中心循环?