재우니의 블로그


<?xml version="1.0" encoding="utf-8"?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
 <siteMapNode title="My Favorites">
   <siteMapNode title="Favorite Sites">
    <siteMapNode title="ASP.NET Home" url="http://www.asp.net" />
    <siteMapNode title="ASP.NET Articles" url="http://www.dotnetcurry.com"/>
    <siteMapNode title="Windows Client" url="http://www.windowsclient.net" />
    <siteMapNode title="Silverlight" url="http://silverlight.net" />
    </siteMapNode>
    <siteMapNode title="Favorite Blogs">
     <siteMapNode title="ScottGu Blog" url="http://weblogs.asp.net/scottgu"/>
     <siteMapNode title="Technology Blog" url="http://www.devcurry.com" />
     <siteMapNode title="SQL Blog" url="http://www.sqlservercurry.com" />
     <siteMapNode title="Food Lovers" url="http://foodatarian.com" />
    </siteMapNode>
    <siteMapNode title="Favorite Social Sites">
      <siteMapNode title="Twitter" url="http://twitter.com/"/>
      <siteMapNode title="FaceBook" url="http://www.facebook.com" />
      <siteMapNode title="LinkedIn" url="http://www.linkedin.com" />
      <siteMapNode title="Orkut" url="http://www.orkut.com" />
    </siteMapNode>
    </siteMapNode>
</siteMap>



위에 ASP.NET SiteMap 이 있습니다. 이것을 가지고 LINQ 이라는 기술을 이용하여 어떻게 데이터 바인딩 컨트롤에 어떻게 처리하는지..
그리고 특정 노드값을 추출하는 방법, 마지막으로 조건문을 기재하여 특정 노드값들만 바인딩하는 구문을 알아볼까 합니다.


1
2
<asp:BulletedList ID="linkList" DisplayMode="HyperLink" runat="server">
</asp:BulletedList>

우선 BulletedList 컨트롤에 바인딩을 할것이므로 VS 에서 해당 컨트롤을 드래그합니다.


1
2
3
4
5
6
7
8
9
XElement xelement = XElement.Load(Server.MapPath("~/web.sitemap"));
    var urlList = xelement.Descendants().Attributes()
       .Where(x => x.Name == "url")
       .Select(x => x.Value);
 
    foreach (string s in urlList)
    {
        linkList.Items.Add(s);
    }


해당 sitemap 파일을 load 한 다음, 안에 있는 노드 중에 url 을 where 구문으로 전부 찾아내고, Value 로 값을 추출합니다.

이는 foreach 구문으로 배열안에 있는 값을 가져다가 BulletedList 컨트롤에 item 을 추가합니다.
해당 웹페이지를 실행하면 아래와 같은 결과값을 얻으실 수 있습니다.




이번에는 약간 깊게 들어가서 url 값만 추출하는게 아니라 title 값도 추출하여 바인딩하는 방법을 알아볼까 합니다.
이 또한 LINQ 기술을 이용할 것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
XElement xelement1 = XElement.Load(Server.MapPath("~/web.sitemap"));       
 var urlDescList = xelement1.Descendants()
 .Where(element => element.LastAttribute.Name.LocalName.Contains("url"))
                    .Select(nd => new
                    {
                        title = nd.Attribute("title").Value,
                        url = nd.Attribute("url").Value
                    });
 
    foreach (var v in urlDescList)
    {
        ListItem li = new ListItem(v.title, v.url);
        linkList.Items.Add(li);                      
    } 


위의 구문을 살펴보면 먼저 url 이 존재하는 노드값을 전부 where 조건으로 추출을 합니다. 그 다음에 title, url 값을
추출하는 것이죠. 이제 이 값을 BulletedList 값에 title 과 url 을 바인딩 합니다.






이젠 특정 상위 노드를 지목하고, 그 하단에 있는 노드의 값들을 추출하는 방법을 알아볼건데요.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
XElement xelement2 = XElement.Load(Server.MapPath("~/web.sitemap"));
var urlDescList1 = xelement2.Descendants()
        // Select node with 'Favorite Social Sites'
.Where(sel => (string)sel.Attribute("title") == "Favorite Social Sites")
.SelectMany(sel => sel.Elements())
.Select(nd => new
{
          title = nd.Attribute("title").Value,
          url = nd.Attribute("url").Value
});
 
    foreach (var s in urlDescList1)
    {
        ListItem li = new ListItem(s.title, s.url);
        linkList.Items.Add(li);           
    }


title 중에 Favorite Social Sites 라는 title 을 갖고 있는 노드가 있습니다. 이를 where 조건으로 찾은 다음에 그 하단의 node 값을 추출하기
위해서 SelectMany() 을 이용하여 시퀀스의 각 요소를 IEnumerable`1에 투영하고 결과 시퀀스를 단일 시퀀스로 평면화 작업을 합니다.
마지막 부분에 title 과 url 값을 추출하는 구문을 입력합니다.



마지막으로 각 부모노드 하단에 자식 노드의 count 를 알아보는 부분을 살펴보겠습니다.


1
2
3
4
5
6
7
8
 XElement xelement3 = XElement.Load(Server.MapPath("~/web.sitemap"));
    var t = xelement3.Descendants()
         .Where(x => x.LastAttribute.Name.LocalName != "url")
      .Select(ele => new
      {
          Name = (string)ele.Attribute("title"),
          Count = ele.Elements().Count()
      });


Count() 라는 함수를 이용하여 해당 하위노드의 카운트값을 얻을 수 있답니다.






LINQ 를 이용하여 ASP.NET SiteMap 을 쿼리하는 방법에 대해 살펴보았습니다. SiteMap 을 다른 방법으로 구현을 하셨다면 약간의 
고생과 어려움을 얻었을거라 생각이 듭니다. 그러나 이번의 아티클을 보셔서 아시겠지만 LINQ 를 이용한다면 간단하게 XML Document 를 쿼리하여 간단히 처리하는 것을 보셨을 겁니다. 만약에 xml document 를 쿼리하는 것에 대해 많이 공부하셨다면 LINQ TO XML 을 사용하여 쉽게 구현하시기 바랍니다.




감사합니다.