0

これを理解するのに最も苦労しています。同じ名前の複数のノードを持つ 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" 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 について次をキャプチャする必要があります: マシン名 VmHost IP

私は 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);
            }
        }
4

2 に答える 2

1

あなたの例は整形式ではありません。タグがありません</Machines>

それを行う別の方法は、LINQtoXMLを使用することです。

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;
}
于 2012-12-18T23:55:33.020 に答える
1

それを 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 };

null もチェックする、属性値を取得するためのヘルパー拡張メソッドを作成することをお勧めします。

ここで重要なことの 1 つは、XML 要素が名前空間にあることを覚えておくことです。クエリを実行するときは、完全な名前空間を指定する必要があります。nsそのため、最初にルート ノードからネームスペース インスタンスを抽出すると便利です。

于 2012-12-18T21:54:08.367 に答える