심재운 블로그


<?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 을 사용하여 쉽게 구현하시기 바랍니다.





감사합니다. 

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band

본문과 관련 있는 내용으로 댓글을 남겨주시면 감사하겠습니다.

비밀글모드

  1. XML 데이터 가져올때 유용하게 쓰이겠네요. 날씨 온도차가 요즘 크네요 아침에는 춥고 낮에는 따뜻하고 감기 조심하세요 ~
    2009.03.11 16:56 신고
    • cdmanii 님도 감기 조심하시고요..항상 좋은 내용 제공해 주셔서 감사합니다. ^__^
      2009.03.11 22:30 신고
  2. 아쉽네요, 위의 방법은 전부 편법이나 우회하는 건데요..

    SiteMap도 XML인데 Linq로 쿼리하는 것을 소개하는 블로그 포스트가 외국이나 한국이나 다 똑같다니...

    아무튼 깔끔하게 번역하고, 정리해서 올려놓으신 글.. 많은 분들에게 도움되는 글 되길 바랍니다.

    감사합니다..
    2009.07.16 07:42