0

私はlinqの使用にかなり慣れていないため、これを理解するのに苦労しています。インターネットを検索していくつかの例を見つけましたが、必要な結果を返すものはありません。マシン名をループできます。次に、それをループして、そのサーバーの機能を取得します。以下は、私の XML の例と、その後に使用しているコードです。2 つの機能を返す代わりに、(すべてのサーバーに対して) 6 つの機能を返します。これを行うためのより良い方法があると確信していますが、多くのバリエーションを試しました。

<?xml version="1.0"?>
<Enterprise xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Version>4.2</Version>
  <Sites>
    <Site>
      <Machines>
        <Machine>
          <MachineName>1950-16-CORE</MachineName>
          <ServerRole>CoreServer</ServerRole>
          <ClientRoles>Core</ClientRoles>
          <Features>
            <Feature>
              <FeatureName>CoreProcess</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
            <Feature>
              <FeatureName>Antivirus</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
          </Features>
        </Machine>
        <Machine>
          <MachineName>1950-16-COREX</MachineName>
          <ServerRole>CoreExpansionServer</ServerRole>
          <ClientRoles>CoreEx</ClientRoles>
          <Features>
            <Feature>
              <FeatureName>CoreExProcess</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
            <Feature>
              <FeatureName>Antivirus</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
          </Features>
        </Machine>
        <Machine>
          <MachineName>1950-16-PRIDB</MachineName>
          <ServerRole>DatabaseServer</ServerRole>
          <ClientRoles>NONE</ClientRoles>
          <Features>
            <Feature>
              <FeatureName>MSSQL</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
            <Feature>
              <FeatureName>Antivirus</FeatureName>
              <FeatureEnabled>true</FeatureEnabled>
            </Feature>
          </Features>
        </Machine>
      </Machines>
    </Site>
  </Sites>
  <GeneratedOn>2013-02-15T18:11:45.0345530Z</GeneratedOn>
</Enterprise>

コード:

    private void ParseXMLData()
    {
        if (File.Exists(xmlFile))
        {
            Cursor.Current = Cursors.WaitCursor;

            XDocument xmlDoc = XDocument.Load(@xmlFile);
            IEnumerable<XElement> siteRows = from siterow in xmlDoc.Descendants("Sites")
                                         select siterow;

            foreach (XElement xEleSite in siteRows)
            {
                IEnumerable<XElement> siteLists = from siteList in xEleSite.Descendants("Site")
                                                  select siteList;

                var machines = from ms in siteLists.Descendants("Machine")
                               select new
                               {
                                   machineName = ms.Element("MachineName").Value,
                                   serverRole = ms.Element("ServerRole").Value,
                                   clientRole = ms.Element("ClientRoles").Value,
                               };

                foreach (var server in machines)                    
                {
                    IEnumerable<XElement> machineRows = from machineRow in siteLists.Descendants("Machines")
                                                        select machineRow;

                    foreach (var currentServer in machineRows)
                    {
                        MessageBox.Show(server.machineName + "\r\n" + server.serverRole + "\r\n" + server.clientRole);

                        IEnumerable<XElement> featureLists = from features in currentServer.Descendants("Features")
                                                             select features;

                        var feature = from fs in featureLists.Descendants("Feature")
                                      select new
                                      {
                                          featureName = fs.Element("FeatureName").Value,
                                          featureEnabled = fs.Element("FeatureEnabled").Value,
                                      };

                        ArrayList alMachineFeature = new ArrayList();
                        ArrayList alMachineFeatureStatus = new ArrayList();

                        foreach (var fs in feature)
                        {
                            alMachineFeature.Add(fs.featureName.ToString());

                            if (fs.featureEnabled.ToString() == "true")
                            {
                                alMachineFeatureStatus.Add("YES");
                            }
                            else
                            {
                                alMachineFeatureStatus.Add("no");
                            }
                        }
                    }
                }
            }
            Cursor.Current = Cursors.Default;
            return;
        }
    }
4

2 に答える 2

1

XElement の子要素のみを取得するには、Descendants() の代わりに Elements() を使用する必要があります。

于 2013-02-26T00:01:03.050 に答える
1

XElement.Descendants("ElementName") は再帰的なメソッドです。子孫の深さに関係なく、"ElementName" という名前のノードのすべての子孫を返します。

一度に 1 レベル下に移動する場合は、現在の要素の直接の子孫の列挙可能なリストに XElement.Elements("ElementName") を使用します。

var machines = xmlDoc.Descendants("Machine");

foreach(var machine in machines)
{
    System.Diagnostics.Debug.WriteLine("Machine: {0}", machine.Element("MachineName"));

    foreach(var feature in machine.Descendants("Feature").Select(f => new { 
              name= f.Element("FeatureName").Value, 
              enabled = f.Element("FeatureEnabled").Value 
            }))
    {
        System.Diagnostics.Debug.WriteLine("  Feature: Name={0}, Enabled={1}", feature.name, feature.enabled);
    }
}
于 2013-02-26T00:15:12.187 に答える