2016-03-22 2 views
0

私は私のナビゲーション要素を維持するために、多次元のXML文書を持っている:親子関係を維持しながらXMLにLinqを使用して多次元XML文書をロードする最良の方法は何ですか?

<level1 title="Personal Banking" controller="PersonalBanking" description="Personal Banking" mainNavOrder="1" > 
 
    <level2 title="Personal Deposits" controller="PersonalBanking" action="PersonalDeposits" mainNavOrder="10" > 
 
     <level3 title="Checking Accounts" controller="PersonalBanking" action="PersonalDeposits" page="CheckingAccounts" /> 
 
     <level3 title="Savings Accounts" controller="PersonalBanking" action="PersonalDeposits" page="SavingsAccounts" /> 
 
     <level3 title="Certificates Of Deposit" controller="PersonalBanking" action="PersonalDeposits" page="CertificatesOfDeposit" /> 
 
    </level2> 
 
    <level2 title="Compare Current Rates" controller="PersonalBanking" action="Rates" mainNavOrder="20" > 
 
     <level3 title="Checking Rates" controller="PersonalBanking" action="Rates" page="CheckingAccounts" /> 
 
    </level2> 
 
    <level2 title="Consumer Lending" controller="PersonalBanking" action="ConsumerLending" mainNavOrder="30" > 
 
     <level3 title="Auto Loans" controller="PersonalBanking" action="ConsumerLending" page="AutoLoans" /> 
 
     <level3 title="Recreational Loans" controller="PersonalBanking" action="ConsumerLending" page="RecreationalLoans" /> 
 
     <level3 title="Home Equity Loans" controller="PersonalBanking" action="ConsumerLending" page="HomeEquityLoans" /> 
 
     <level3 title="Other Loans" controller="PersonalBanking" action="ConsumerLending" page="OtherLoans" /> 
 
    </level2> 
 
    <level2 title="Personal Services" controller="PersonalBanking" action="PersonalServices" mainNavOrder="40" > 
 
     <level3 title="ATM &amp; Debit Cards" controller="PersonalBanking" action="PersonalServices" page="ATMDebitCards" /> 
 
     <level3 title="Online Banking &amp; Bill Payment" controller="PersonalBanking" action="PersonalServices" page="OnlineBankingBillPayment" /> 
 
     <level3 title="Overdraft Protection" controller="PersonalBanking" action="PersonalServices" page="OverdraftProtection" /> 
 
    </level2> 
 
    <level2 title="Education Center" controller="EducationCenter" mainNavOrder="50" /> 
 

 
    </level1>

前のXMLの例では、ノードの部分だけです。 LinqをXMLに使用して読み込んでいます。これはちょうどそれを行うには非常に醜い方法であるようだ。私はこれをリファクタリングしたいと思いますが、実際にどのように知っていません。

var pages = sitemapData.Descendants("level1") 
         .Select(p1 => new SitemapNode 
         { 
          Title = (string)p1.Attribute("title"), 
          Action = (string)p1.Attribute("action") ?? "Index", 
          Controller = (string)p1.Attribute("controller"), 
          Page = (string)p1.Attribute("page") ?? "", 
          Description = (string)p1.Attribute("description") ?? "", 
          Blank = bool.Parse((string)p1.Attribute("blank") ?? "false"), 
          Level = p1.Ancestors().Count(), 
          mainNavOrder = (int?)p1.Attribute("mainNavOrder") ?? 0, 
          sections = p1.Elements("alternativeSection") 
            .Select(n => (string)n.Attribute("name")), 
          subNodes = p1.Elements("level2") 
           .Select(p2 => new SitemapNode 
           { 
            Title = (string)p2.Attribute("title"), 
            Action = (string)p2.Attribute("action") ?? "Index", 
            Controller = (string)p2.Attribute("controller"), 
            Page = (string)p2.Attribute("page") ?? "", 
            Description = (string)p2.Attribute("description") ?? "", 
            Blank = bool.Parse((string)p2.Attribute("blank") ?? "false"), 
            Level = p2.Ancestors().Count(), 
            mainNavOrder = (int?)p2.Attribute("mainNavOrder") ?? 0, 
            sections = p2.Elements("alternativeSection") 
                .Select(n => (string)n.Attribute("name")), 
            subNodes = p2.Elements("level3") 
            .Select(p3 => new SitemapNode 
            { 
             Title = (string)p3.Attribute("title"), 
             Action = (string)p3.Attribute("action") ?? "Index", 
             Controller = (string)p3.Attribute("controller"), 
             Page = (string)p3.Attribute("page") ?? "", 
             Description = (string)p3.Attribute("description") ?? "", 
             Blank = bool.Parse((string)p3.Attribute("blank") ?? "false"), 
             Level = p3.Ancestors().Count(), 
             mainNavOrder = (int?)p3.Attribute("mainNavOrder") ?? 0, 
             sections = p3.Elements("alternativeSection") 
                .Select(n => (string)n.Attribute("name")) 
            }) 

            .OrderBy(n => n.Title) 
           } 

           ) 
           .OrderBy(n => n.Title) 
         }); 
      Sitemap.AddRange(pages.ToList<SitemapNode>()); 

子/親の関係を維持しながらこれらをロードする方が良いでしょうか?それが動作して以来私は心配する必要がありますか?

+0

グッド藩主の男、このコードを試してみてください? – Jonesopolis

+0

ええ、私は完璧に近いものではないことを知っています。それが私が尋ねた理由です。アドバイスをありがとう、私は間違いなくデシリアライザが行く方法だと思う、私はあまりにもそれに精通していないので、私は将来それを調べます。ありがとうございました。 – EHaltom

答えて

0

は、あなただけのフレームワークが提供するデシリアライザを使用しない理由

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xml = 
      "<Root>" + 
      "<level1 title=\"Personal Banking\" controller=\"PersonalBanking\" description=\"Personal Banking\" mainNavOrder=\"1\">" + 
       "<level2 title=\"Personal Deposits\" controller=\"PersonalBanking\" action=\"PersonalDeposits\" mainNavOrder=\"10\">" + 
        "<level3 title=\"Checking Accounts\" controller=\"PersonalBanking\" action=\"PersonalDeposits\" page=\"CheckingAccounts\"/>" + 
        "<level3 title=\"Savings Accounts\" controller=\"PersonalBanking\" action=\"PersonalDeposits\" page=\"SavingsAccounts\"/>" + 
        "<level3 title=\"Certificates Of Deposit\" controller=\"PersonalBanking\" action=\"PersonalDeposits\" page=\"CertificatesOfDeposit\"/>" + 
       "</level2>" + 
       "<level2 title=\"Compare Current Rates\" controller=\"PersonalBanking\" action=\"Rates\" mainNavOrder=\"20\">" + 
        "<level3 title=\"Checking Rates\" controller=\"PersonalBanking\" action=\"Rates\" page=\"CheckingAccounts\"/>" + 
       "</level2>" + 
       "<level2 title=\"Consumer Lending\" controller=\"PersonalBanking\" action=\"ConsumerLending\" mainNavOrder=\"30\">" + 
        "<level3 title=\"Auto Loans\" controller=\"PersonalBanking\" action=\"ConsumerLending\" page=\"AutoLoans\"/>" + 
        "<level3 title=\"Recreational Loans\" controller=\"PersonalBanking\" action=\"ConsumerLending\" page=\"RecreationalLoans\"/>" + 
        "<level3 title=\"Home Equity Loans\" controller=\"PersonalBanking\" action=\"ConsumerLending\" page=\"HomeEquityLoans\"/>" + 
        "<level3 title=\"Other Loans\" controller=\"PersonalBanking\" action=\"ConsumerLending\" page=\"OtherLoans\"/>" + 
       "</level2>" + 
       "<level2 title=\"Personal Services\" controller=\"PersonalBanking\" action=\"PersonalServices\" mainNavOrder=\"40\">" + 
        "<level3 title=\"ATM &amp; Debit Cards\" controller=\"PersonalBanking\" action=\"PersonalServices\" page=\"ATMDebitCards\"/>" + 
        "<level3 title=\"Online Banking &amp; Bill Payment\" controller=\"PersonalBanking\" action=\"PersonalServices\" page=\"OnlineBankingBillPayment\"/>" + 
        "<level3 title=\"Overdraft Protection\" controller=\"PersonalBanking\" action=\"PersonalServices\" page=\"OverdraftProtection\"/>" + 
       "</level2>" + 
       "<level2 title=\"Education Center\" controller=\"EducationCenter\" mainNavOrder=\"50\"/>" + 
       "</level1>" + 
       "</Root>"; 


      XElement sitemapData = XElement.Parse(xml); 

      var pages = sitemapData.Descendants("level1") 
         .Select(p1 => SitemapNode.GetNode(p1,1) 
      ); 
      List<SitemapNode> Sitemap = new List<SitemapNode>(); 
      Sitemap.AddRange(pages.ToList<SitemapNode>()); 

     } 


     public class SitemapNode 
     { 
      public string Title { get; set; } 
      public string Action { get; set; } 
      public string Controller { get; set; } 
      public string Page { get; set; } 
      public string Description { get; set; } 
      public bool Blank { get; set; } 
      public int Level { get; set; } 
      public int? mainNavOrder { get; set; } 
      public string[] sections { get; set; } 
      public SitemapNode[] subNodes { get; set; } 

      public static SitemapNode GetNode(XElement p3, int level) 
      { 
       return new SitemapNode 
       { 
        Title = (string)p3.Attribute("title"), 
        Action = (string)p3.Attribute("action") ?? "Index", 
        Controller = (string)p3.Attribute("controller"), 
        Page = (string)p3.Attribute("page") ?? "", 
        Description = (string)p3.Attribute("description") ?? "", 
        Blank = bool.Parse((string)p3.Attribute("blank") ?? "false"), 
        Level = p3.Ancestors().Count(), 
        mainNavOrder = (int?)p3.Attribute("mainNavOrder") ?? 0, 
        sections = p3.Elements("alternativeSection") 
           .Select(n => (string)n.Attribute("name")).ToArray(), 
        subNodes = p3.Elements("level" + (level + 1).ToString()).Select(pn => GetNode(pn, level + 1)).ToArray() 
       }; 

      } 
     } 
    } 
} 
+0

これは完璧に動作します。時間を割いて私を助けてくれてありがとう。それは有り難いです。 – EHaltom

+0

マイナス2点を得たのはなぜですか? GetNodeをクラスSitemapNodeに入れるコードを修正しました。更新プログラムを必ず使用してください。 – jdweng

+0

私は-1を入れていませんでした。実際には、+1を付けて答えとしてマークしました。しかし、はい、ありがとう。私はそのメソッドをSitemapNodeクラスに入れました。 もう一度ありがとうございます。 – EHaltom

関連する問題