问题循环通过后代

时间:2013-02-25 23:36:08

标签: c# linq linq-to-xml

我对使用linq很新,我很难搞清楚这一点。我搜索了互联网,发现了几个例子,但没有一个回复我需要的结果。我能够遍历机器名称。现在我想通过它来获取该服务器的功能。下面是我的XML示例,后面是我正在使用的代码。它没有返回两个功能,而是返回其中的六个(适用于所有服务器)。我确信有更好的方法可以做到这一点,但我尝试了很多变化。

<?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;
        }
    }

1 个答案:

答案 0 :(得分:1)

XElement.Descendants(“ElementName”)是一个递归方法:它将返回名为“ElementName”的所有节点的后代,无论这些后代有多深。

如果你想一次降低一级,可以使用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);
    }
}