2010-01-14 6 views
3

저는 LINQ를 처음 사용하고있어서 문제가 있습니다. 내가 원하는 갤러리의 ID를 알고, 어쨌든LINQ를 사용하여 임의의 XML 노드 선택

<?xml version="1.0" encoding="utf-8" ?> 
<Galleries> 
    <Gallery ID="10C31804CEDB42693AADD760C854ABD" Title="Test1"> 
     <Description>The first test gallery. Picture of a cat and Wilford Brimley. Can you tell the difference?</Description> 
     <Images> 
     <Image Title="t1Image1" FileName="tcats.jpg" /> 
     <Image Title="t1Image2" FileName="twb.jpg" /> 
     </Images> 
    </Gallery> 
    <Gallery ID="0420EC15405B488E1E0F157AC823A6" Title="Test2"> 
     <Description>The second test gallery. A large image of Wilford Brimley and various cats. The cats will be on the right.</Description> 
     <Images> 
     <Image Title="t2Image1" FileName="wilfordbrimley.jpg" /> 
     </Images> 
    </Gallery> 
</Galleries> 

,하지만 난 임의의 이미지 중 하나를 선택합니다 : 내가 이렇게 보이는 파일이 있습니다. 이 작업을 수행 할 수있는 LINQ 문이 있습니까?

답변

3

갤러리의 이미지를 Random.Next()로 정렬 한 다음 첫 번째 요소를 선택할 수 있습니까?

나는 linq2xml에 대해 잘 모릅니다하지만 저는 여기에

static void Main(string[] args) 
{ 
    Random rnd = new Random(); 
    XDocument galleries = XDocument.Load(@"C:\Users\John Boker\Documents\Visual Studio 2008\Projects\ConsoleApplication1\ConsoleApplication1\Galleries.xml"); 
    var image = (from g in galleries.Descendants("Gallery") 
       where g.Attribute("ID").Value == "10C31804CEDB42693AADD760C854ABD" 
       select g.Descendants("Images").Descendants("Image").OrderBy(r=>rnd.Next()).First()).First(); 
    Console.WriteLine(image); 
    Console.ReadLine(); 
} 

나는 선택이 다르게 많은 일을 할 수있는 확신 해낸거야,하지만 내가 그것을 무작위로 작업하기 위해 무슨 짓을했는지. 다음 일.

+0

매우 영리한 솔루션 따라서, 나는 다음과 같은 사용합니다. –

+0

Random.Next()를 사용하여 무작위 갤러리를 선택하는 방법을 알아 냈습니다.하지만 Gallery ID를받은 갤러리에서 임의의 이미지를 선택하려면 어떻게해야합니까? 죄송합니다, LINQ가 지금 내 머리 위로 가고 있습니다. –

+1

@OSMan : 갤러리가 포함 된'XElement' 또는'XNode'를 사용하는 경우'node.Element ("Images")'를 사용하여 images 요소를 가져옵니다. –

1

다음은 노드 수를 계산하는 데 의존하는 몇 가지 해결책입니다. 대단히 효율적은 아니지만 많은 Linq 컬렉션 유형이 IEnumerable으로 노출되어 있기 때문에 더 잘할 수 있다고 생각하지 않습니다.

XElement GetRandomImage(XElement images) 
{ 
    Random rng = new Random(); 
    int numberOfImages = images.Elements("Image").Count(); 

    return images.Elements("Image").Skip(rng.Next(0, numberOfImages)).FirstOrDefault(); 
} 

XElement GetRandomImage(XElement images) 
{ 
    Random rng = new Random(); 
    IList<XElement> images = images.Elements("Image").ToList(); 

    return images.Count == 0 : 
     null ? 
     images[rng.Next(0, images.Count - 1)]; 
} 
0

가 나는 n 선택한 갤러리에서 이미지의 숫자가 O(n log n)하는 종류의 사용으로 선택한 답변을 사용하지 않는 것이 좋습니다. O(1) 시간의 목록에서 임의의 항목을 선택할 수 있습니다. 여기

using(StreamReader sr = new StreamReader(File.Open(path, FileMode.Open))) { 
    XDocument galleries = XDocument.Load(sr); 
    string id = "10C31804CEDB42693AADD760C854ABD"; 
    var query = (from gallery in galleries.Descendants("Galleries") 
              .Descendants("Gallery") 
       where (string)gallery.Attribute("ID") == id 
       select gallery.Descendants("Images") 
           .Descendants("Image") 
       ).SingleOrDefault(); 
    Random rg = new Random(); 
    var image = query.ToList().RandomItem(rg); 
    Console.WriteLine(image.Attribute("Title")); 
} 

내가 사용하고 :

static class ListExtensions { 
    public static T RandomItem<T>(this List<T> list, Random rg) { 
     if(list == null) { 
      throw new ArgumentNullException("list"); 
     } 
     if(rg == null) { 
      throw new ArgumentNullException("rg"); 
     } 
     int index = rg.Next(list.Count); 
     return list[index]; 
    } 
} 
관련 문제