2016-09-01 7 views
-1

私は最終的に、取り除かれるアイテムを解析して、作業中のユーザーアクセスプロビジョニングシステムで使用されるXMLファイルをクリーンアップするスクリプトを作成しています。 XML文書は以下のように、子/親ノードの様々なレベルがあります。親ノードに基づいて一連のXMLノードをグループ化します

<Enterprise> 
<Channel name="a"> 
<busunit name="one"> 
    <dept name="x"> 
    <role name ="role1"> 
    <role name="role2"> 
    </dept> 
    <dept name="y"> 
    <dept name="z"> 
</busunit > 
<busunit name="two"> 
<busunit name="three">  
</Channel> 
<Channel name="b" > 
<Channel name="c"> 
</Enterprise> 

私は両親に基づいて文書やグループの項目を読み込むされてやりたいと思っていますが、私は出てくるのに苦労していますさまざまなノードレベルのためにこれを行うための強固な方法です。

私は、ビジネスユニットのリストを格納する一連のリストを使用し始めました。これは、最終的に役割のリスト(本質的に多次元リスト)を格納する部門のリストを格納しますがこれを考えていると、デバッグするのが非常に速く、悪夢に追いつかなくなる可能性があります。

いくつか他のもの

は注意する:

  • チャネルにおけるbusunitsのないセット数はありませんが、またbusunitでDEPTSのセット数OR DEPTSにおける役割のセット数がある
  • チャネル/バスユニット/部門間にバスユニット/部門/役割の名前が重複しています(これが原因でクリーンアップが必要です)。

これは曖昧ではありませんが、私が知りたいことです要するに: その他の代替手段複数の親/子ノードをグループ化して格納するための多次元リスト以外の方法はありますか?

ありがとうございます!

答えて

1

は、それが簡単に

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 
using System.Data; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 
      DataTable dt = new DataTable(); 

      dt.Columns.Add("Channel", typeof(string)); 
      dt.Columns.Add("busunit", typeof(string)); 
      dt.Columns.Add("dept", typeof(string)); 
      dt.Columns.Add("role", typeof(string)); 

      foreach (XElement channel in doc.Descendants("Channel")) 
      { 
       string channelName = (string)channel.Attribute("name"); 
       List<XElement> busunits = channel.Elements("busunit").ToList(); 
       if (busunits.Count == 0) 
       { 
        dt.Rows.Add(new object[] { channelName }); 
       } 
       else 
       { 
        foreach (XElement busunit in busunits) 
        { 
         string busunitName = (string)busunit.Attribute("name"); 
         List<XElement> depts = busunit.Elements("dept").ToList(); 
         if (depts.Count == 0) 
         { 
          dt.Rows.Add(new object[] { channelName, busunitName }); 
         } 
         else 
         { 
          foreach (XElement dept in depts) 
          { 
           string deptName = (string)dept.Attribute("name"); 
           List<XElement> roles = dept.Elements("role").ToList(); 
           if (roles.Count == 0) 
           { 
            dt.Rows.Add(new object[] { channelName, busunitName, deptName }); 
           } 
           else 
           { 
            foreach (XElement role in roles) 
            { 
             string roleName = (string)role.Attribute("name"); 
             dt.Rows.Add(new object[] { channelName, busunitName, deptName, roleName }); 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
      dt = dt.AsEnumerable() 
       .OrderBy(m => m.Field<string>("Channel")) 
       .ThenBy(n => n.Field<string>("busunit")) 
       .ThenBy(o => o.Field<string>("dept")) 
       .ThenBy(p => p.Field<string>("role")) 
       .CopyToDataTable(); 

      //remove duplicates 
      for (int row = dt.Rows.Count - 2; row >= 0; row--) 
      { 
       if ((dt.Rows[row].Field<object>("Channel") == dt.Rows[row + 1].Field<object>("Channel")) && 
        (dt.Rows[row].Field<object>("busunit") == dt.Rows[row + 1].Field<object>("busunit")) && 
        (dt.Rows[row].Field<object>("dept") == dt.Rows[row + 1].Field<object>("dept")) && 
        (dt.Rows[row].Field<object>("role") == dt.Rows[row + 1].Field<object>("role"))) 
       { 
        dt.Rows[row + 1].Delete(); 
       } 
      } 
      dt.AcceptChanges(); 

     } 
    } 
} 
を削除するようになりますデータテーブルにデータを入れてみてください
関連する問題