2009-02-02 26 views
3

我目前正在研究Silverlight應用程序,並需要將XML數據轉換爲適合數據綁定的適當對象。本次討論的基本類定義是:LINQ to XML:將多重級別摺疊爲單個列表

public class TabularEntry 
    { 
     public string Tag { get; set; } 
     public string Description { get; set; } 
     public string Code { get; set; } 
     public string UseNote { get; set; } 
     public List<string> Excludes { get; set; } 
     public List<string> Includes { get; set; } 
     public List<string> Synonyms { get; set; } 
     public string Flags { get; set; } 
     public List<TabularEntry> SubEntries { get; set; } 
    } 

可能出現在飼料這個對象的XML的示例如下:

<I4 Ref="1">222.2 
    <DX>Prostate</DX> 
    <EX> 
     <I>adenomatous hyperplasia of prostate (600.20-600.21)</I> 
     <I>prostatic: 
      <I>adenoma (600.20-600.21)</I> 
      <I>enlargement (600.00-600.01)</I> 
      <I>hypertrophy (600.00-600.01)</I> 
     </I> 
    </EX> 
    <FL>M</FL> 
</I4> 

因此,各個節點映射到特定屬性。這個問題的關鍵是<EX><I>節點。 <EX>節點將包含一個或多個<I>節點的集合,並且在本例中與上述類定義中的'Excludes'屬性匹配。

這裏是挑戰(對我來說)。我無法控制發佈此XML的Web服務,因此更改它不是一種選擇。您會注意到,在此示例中,一個<I>節點還包含另一個一個或多個節點的集合。我希望我可以使用LINQ to XML查詢,這將允許我將兩個級別合併到一個集合中,並使用一個字符來分隔較低級別的項目,因此在本例中,當LINQ查詢返回一個TablularEntry對象,它將包含排除會出現該項目的集合,如下所示:

  • *腺瘤(600.20-600.21)
    • 前列腺 (600.20-600.21)
    • 前列腺的腺瘤樣增生*放大(600.00-600.01)
    • *肥大(600.00-600.01)

    所以,在XML中的最後3項實際上是第二項的子對象,但對象的排除屬性,它們是同一個集合中的所有部分,與包含標識符字符/字符串的以前的子對象。

    我有我在下面使用的LINQ查詢的開始,我不能完全弄清楚將爲我整合子對象的位。因爲它現在存在的代碼是:

    List<TabularEntry> GetTabularEntries(XElement source) 
         { 
          List<TabularEntry> result; 
    
          result = (from tabularentry in source.Elements() 
             select new TabularEntry() 
             { 
              Tag = tabularentry.Name.ToString(), 
              Description = tabularentry.Element("DX").ToString(), 
              Code = tabularentry.FirstNode.ToString(), 
              UseNote = tabularentry.Element("UN") == null ? null : tabularentry.Element("UN").Value, 
              Excludes = (from i in tabularentry.Element("EX").Elements("I") 
                  select i.Value).ToList() 
             }).ToList(); 
    
          return result; 
         } 
    

    我想,我需要一個窩FROM語句的

    排除=(從我...)

    聲明收集子節點,但不能完全解決它。當然,這可能是因爲我在雜草中偏離了我的邏輯。

    如果您需要更多信息來回答,請隨時詢問。

    由於提前,

    史蒂夫

  • 回答

    2

    試試這個輸入:

    <EX> 
        <I>adenomatous hyperplasia of prostate (600.20-600.21)</I> 
        <I>prostatic: 
         <I>adenoma (600.20-600.21)</I> 
         <I>enlargement (600.00-600.01)</I> 
         <I>hypertrophy (600.00-600.01) 
          <I>Bla1</I> 
          <I>Bla2 
           <I>BlaBla1</I> 
          </I> 
          <I>Bla3</I> 
         </I> 
          </I> 
    </EX> 
    

    結果:

    * adenomatous hyperplasia of prostate (600.20-600.21) 
    * prostatic: 
    * *adenoma (600.20-600.21) 
    * *enlargement (600.00-600.01) 
    * *hypertrophy (600.00-600.01) 
    * **Bla1 
    * **Bla2 
    * ***BlaBla1 
    * **Bla3 
    
    +0

    感謝布魯諾。我剛剛打電話來處理另一種產品中的問題。我會盡快嘗試。 – 2009-02-02 19:14:54

    0

    後人將讓你所有的I孩子。 FirstNode將有助於從其子女的價值中分離出prostatic:的價值。在prostatic:的值中有一個返回字符,我用Trim刪除了該字符。

    XElement x = XElement.Parse(@" 
    <EX> 
        <I>adenomatous hyperplasia of prostate (600.20-600.21)</I> 
        <I>prostatic: 
        <I>adenoma (600.20-600.21)</I> 
        <I>enlargement (600.00-600.01)</I> 
        <I>hypertrophy (600.00-600.01)</I> 
        </I> 
    </EX>"); 
    // 
    List<string> result = x 
        .Descendants(@"I") 
        .Select(i => i.FirstNode.ToString().Trim()) 
        .ToList(); 
    

    下面是一個哈希的方式來獲取這些星號。我沒有時間去改進它。如果你需要的 「我」,你可以做類似目前的嵌套層次

    List<TabularEntry> GetTabularEntries(XElement source) 
        { 
         List<TabularEntry> result; 
    
         result = (from tabularentry in source.Elements() 
            select new TabularEntry() 
            { 
             Tag = tabularentry.Name.ToString(), 
             Description = tabularentry.Element("DX").ToString(), 
             Code = tabularentry.FirstNode.ToString(), 
             UseNote = tabularentry.Element("UN") == null ? null : tabularentry.Element("UN").Value, 
             Excludes = (from i in tabularentry.Element("EX").Descendants("I") 
                select (i.Parent.Name == "I" ? "*" + i.Value : i.Value)).ToList() 
    
            }).ToList(); 
    
         return result; 
        } 
    

    (編輯)

    List<TabularEntry> GetTabularEntries(XElement source) 
        { 
         List<TabularEntry> result; 
    
         result = (from tabularentry in source.Elements() 
            select new TabularEntry() 
            { 
             Tag = tabularentry.Name.ToString(), 
             Description = tabularentry.Element("DX").ToString(), 
             Code = tabularentry.FirstNode.ToString(), 
             UseNote = tabularentry.Element("UN") == null ? null : tabularentry.Element("UN").Value, 
             Excludes = (from i in tabularentry.Element("EX").Descendants("I") 
                select (ElementWithPrefix(i, '*'))).ToList() 
    
            }).ToList(); 
    
         return result; 
        } 
    
        string ElementWithPrefix(XElement element, char c) 
        { 
         string prefix = ""; 
         for (XElement e = element.Parent; e.Name == "I"; e = e.Parent) 
         { 
          prefix += c; 
         } 
         return prefix + ExtractTextValue(element); 
        } 
    
        string ExtractTextValue(XElement element) 
        { 
         if (element.HasElements) 
         { 
          return element.Value.Split(new[] { '\n' })[0].Trim(); 
         } 
         else 
          return element.Value.Trim(); 
        } 
    

    List<string> result2 = x 
        .Descendants(@"I") 
        .Select(i => 
        new string(Enumerable.Repeat('*', i.Ancestors(@"I").Count()).ToArray()) 
        + i.FirstNode.ToString().Trim()) 
        .ToList();