簡體   English   中英

使用Linq遞歸查詢XML

[英]Recursively Query XML with Linq

<tok id="9993" type="group">
  <tok id="144" type="atom" soff="686" eoff="693">
    <txt>popular</txt>
  </tok>
  <tok id="145" type="group">
     <tok id="144" type="atom" soff="686" eoff="693">
       <txt>movie</txt>
     </tok>
     <tok id="145" type="atom" soff="697" eoff="703">
       <txt>characters</txt>
     </tok>
  </tok>
</tok>

我有一個XML文檔,我需要獲取soff和eoff的值,但這些值可以嵌套。 我嘗試過使用SelectMany(),但我做錯了。 以上是該文件的摘錄。 我基本上想得到所有類型為“atom”的“tok”,以便我可以從每個中獲取我需要的兩個值。 我的查詢是這樣的:

 var queryHeadsTails2 = from h in xmlDoc.Root.Descendants("tok")
                        where (h.Attribute("id").Value == elem.entityID && h.Attribute("type").Value == "group")
                        select h;

我可以使用SelectMany來獲取type =“atom”的所有行,還是有更好的方法?

答案如下

var groups = xmlDoc.Descendants("tok").Where(x => (string)x.Attribute("type") == "group" && x.Elements("tok").Where(y => (string)y.Attribute("type") == "atom").Any()).Select(x => new {
                        id = (string)x.Attribute("id"),
                        atoms = x.Elements("tok").Where(y => (string)y.Attribute("type") == "atom").ToList()
                    }).ToList();

非常接近,但它在這一部分失敗了(試圖獲得組ID 153527的eoff和soff):

<tok id="153619" type="group">
    <tok id="80" type="atom" soff="388" eoff="390">
      <txt>in</txt>
    </tok>
    <tok id="153527" type="group">
      <tok id="153526" type="group">
        <tok id="81" type="atom" soff="391" eoff="396" no-space="true">
          <txt>today</txt>
        </tok>
        <tok id="82" type="atom" soff="396" eoff="398">
          <txt>'s</txt>
        </tok>
      </tok>
      <tok id="128206" type="group">
        <tok id="6360" type="group">
          <tok id="83" type="atom" soff="399" eoff="404">
            <txt>action</txt>
          </tok>
          <tok id="84" type="atom" soff="405" eoff="409">
            <txt>movie</txt>
          </tok>
        </tok>
        <tok id="85" type="atom" soff="410" eoff="418" no-space="true">
          <txt>industry</txt>
        </tok>
      </tok>
    </tok>
  </tok>

在我得到我想要的小組后,有沒有辦法讓它變平? 有點像我從上面開始的地方?

試試以下:

           var groups = doc.Descendants("tok").Where(x => (string)x.Attribute("type") == "group" && x.Elements("tok").Where(y => (string)y.Attribute("type") == "atom").Any()).Select(x => new { id = (string)x.Attribute("id"), atoms = x.Elements("tok").Where(y => (string)y.Attribute("type") == "atom").ToList() }).ToList();

如果VB'ers找到這篇文章......

首先是一些測試數據

Dim xe As XElement
'to load
'  xe = XElement.Load("path / URI")
'for testing
xe = <tok id="9993" type="group">
         <tok id="144" type="atom" soff="687" eoff="693">
             <txt>popular</txt>
         </tok>
         <tok id="145" type="group">
             <tok id="144" type="atom" soff="686" eoff="693">
                 <txt>movie</txt>
             </tok>
             <tok id="145" type="atom" soff="697" eoff="703">
                 <txt>characters</txt>
             </tok>
         </tok>
     </tok>

然后選擇具有@type =“atom”的元素的代碼

  Dim ie As IEnumerable(Of XElement) = xe...<tok>.Where(Function(el) el.@type = "atom")

最后檢查每個選定的元素

    For Each el As XElement In ie
        Debug.WriteLine("soff = {0}, eoff = {1}", el.@soff, el.@eoff)
    Next

非常感謝你的幫助。 這讓我想到了這個似乎觸及所有情況:

var groups = from h in xmlDoc.Root.Descendants("tok")
             where (h.Attribute("id").Value == elem.entityID && h.Attribute("type").Value == "group")
             select new
             {
                  id = h.Attribute("id").Value,
                  atoms = h.Descendants("tok").Where(y => (string)y.Attribute("type") == "atom").ToList()
              };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM