嵌套linq查询

问题描述:

我正在使用这样的xml文件。嵌套linq查询

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> 
    <Body> 
    <Element1> 
     <Element2 day="2009-10-18"> 
     <Element3 name="Joe"> 
      <Element4 time="1"> 
      <Element5 amount="0" price="16.58"/> 
      <Element5 amount="1" price="18.58"/> 
      <Element5 amount="2" price="20.58"/> 
      </Element4> 
     </Element3> 
     <Element3 name="Fred"> 
      <Element4 time="5"> 
      <Element5 amount="1" price="15.41"/> 
      <Element5 amount="2" price="16.41"/> 
      <Element5 amount="3" price="17.41"/> 
      <Element5 amount="4" price="18.41"/> 
      </Element4> 
     </Element3> 
     </Element2> 
    </Element1> 
    </Body> 
</Envelope> 

我需要通过所有的元素3节点循环,然后通过所有的元素5节点循环来得到类似这样的输出。

day, name, time, amount, price 
2009-10-18, Joe, 1, 0, 16.58 
2009-10-18, Joe, 1, 1, 18.58 
2009-10-18, Joe, 1, 2, 20.58 
2009-10-18, Joe, 1, 1, 16.58 
2009-10-18, Fred, 5, 0, 15.41 
etc 

我的LINQ查询要做到这一点看起来像下面的我以为是伟大的,直到我意识到这只是霎那便来到了第一个元素5点。

XDocument doc = XDocument.Load(@"myfile.xml"); 
     DataContext st = new DataContext(); 

     var docxml = from c in doc.Elements("Envelope").Elements("Body").Elements("Element1").Elements("Element2").Elements("Element3") 
        select new mytable() 
        { 
         MyKey = Guid.NewGuid(), 
         day = Convert.ToDateTime(c.Parent.Attribute("day").Value) 
         name = c.FirstAttribute.Value, 
         hour = Convert.ToInt32(c.Element("Element4").FirstAttribute.Value), 
         price = Convert.ToDecimal(c.Element("Element4").Element("Element5").Attribute("price").Value), 
         amount = Convert.ToDecimal(c.Element("Element4").Element("Element5").Attribute("amount").Value) 

        }; 
     st.mytable.InsertAllOnSubmit(docxml); 
     st.SubmitChanges(); 

我该如何循环以包含所有的Element5节点?

每个from-statement基本上都是一个foreach-loop(简单的想法)。
注:我不得不改变一些家长关系

XDocument doc = XDocument.Load(@"myfile.xml"); 
DataContext st = new DataContext(); 

var docxml = from c in doc.Elements("Envelope").Elements("Body").Elements("Element1").Elements("Element2").Elements("Element3").Elements("Element4") 
      from e in c.Elements("Element5") 
      select new mytable() 
      { 
       MyKey = Guid.NewGuid(), 
       day = Convert.ToDateTime(c.Parent.Parent.Attribute("day").Value) 
       name = c.Parent.FirstAttribute.Value, 
       hour = Convert.ToInt32(c.FirstAttribute.Value), 
       price = Convert.ToDecimal(e.Attribute("price").Value), 
         amount = Convert.ToDecimal(e.Attribute("amount").Value) 

      }; 

st.mytable.InsertAllOnSubmit(docxml); 
st.SubmitChanges(); 

你可以使代码更易读一点通过让语句和更好的名字:

var docxml = from element4 in doc.Elements("Envelope").Elements("Body").Elements("Element1").Elements("Element2").Elements("Element3").Elements("Element4") 
      let element3 = element4.Parent 
      let element2 = element3.Parent 
      from element5 in c.Elements("Element5") 
    ... 

我可以不测试代码,因为我在我的MacBook上。希望这可以帮助。

+0

+1“from = foreach” – dFlat 2011-09-29 05:44:01