2009-06-02 85 views
1

我最近問了一個關於如何Save a list with nested elements to XML的問題,但現在我正在嘗試爲該類編寫加載程序並遇到問題。使用LiNQ加載嵌套的XML

我試圖扭轉給出的答案(謝謝Jon)。

我相信我的核心LINQ查詢是好的,這是我正在努力的遞歸。 這裏是我到目前爲止的代碼(爲清晰起見,我已經發布了整個CPP爲是)

/// <summary> 
/// 
/// </summary> 
public class ErrorType 
{ 
    List<ErrorType> _childErrors; 

    public String Name { get; set; } 
    public bool Ignore { get; set; } 

    public List<ErrorType> ChildErrors { get; protected set; } 
} 

/// <summary> 
/// 
/// </summary> 
public class ErrorList 
{ 
    public List<ErrorType> ChildErrors { get; protected set; } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="xml"></param> 
    public void FilterErrors(XElement xml) 
    { 
     //Convert to ErrorList 
     //Write back out to XML but not writing out anything with errors 
     //Send XML on its way 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="el"></param> 
    /// <returns></returns> 
    private XElement ErrorListToXml(ErrorList el) 
    { 
     // Need to declare in advance to call within the lambda. 
     Func<ErrorType, XElement> recursiveGenerator = null; 
     recursiveGenerator = error => new XElement 
      (error.Name, 
      new XAttribute("Ignore", error.Ignore), 
      error.ChildErrors.Select(recursiveGenerator)); 

     var element = new XElement 
        ("ErrorList", 
        ChildErrors.Select(recursiveGenerator)); 

     Console.WriteLine(element); 

     return element; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="xd"></param> 
    /// <returns></returns> 
    private ErrorList FromXmlToErrorList(XElement xd) 
    { 
     //Prepare lambda 
     Func<ErrorType, XElement> recursiveGenerator = null; 
     recursiveGenerator = error => new List<ErrorType> 
      (error.Name, 
      new XAttribute("Ignore", error.Ignore), 
      error.ChildErrors.Select(recursiveGenerator)); 

     List<ErrorType> typeList = (from error in xd.Descendants() 
         select new ErrorType 
         { 
          Name = error.Value, 
          Ignore = bool.Parse(error.Attribute("Ignore").Value), 
          ChildErrors= error.Elements().Select() 
         }).ToList<ErrorType>(); 

     ErrorList el = new ErrorList(); 
     el.ChildErrors = typeList; 
     return el; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public void Save() 
    { 
     XElement xml = ErrorListToXml(this); 
     xml.Save("errorlist.xml"); 
    } 

    public void Load() 
    { 

    } 
} 

三江源

回答

3

我得到了它的東西,如工作:

XDocument doc = XDocument.Parse(xml); 

    Func<XElement, ErrorType> nodeReader = null; 
    nodeReader = el => new ErrorType(
     el.Elements().Select(nodeReader)) { 
     Name = el.Name.LocalName, 
     Ignore = (bool)el.Attribute("Ignore"), 
    }; 

    ErrorList list = new ErrorList(
     doc.Root.Elements().Select(nodeReader)); 

具有所添加合適的構造函數:

public ErrorType(IEnumerable<ErrorType> children) { 
    ChildErrors = new List<ErrorType>(children); 
} 
public ErrorType() { ChildErrors = new List<ErrorType>(); } 

public ErrorType(IEnumerable<ErrorType> children) { 
    ChildErrors = new List<ErrorType>(children); 
} 
public ErrorType() { ChildErrors = new List<ErrorType>(); } 

有什麼用?

+0

這個工作非常漂亮三江源。我不完全確定它是如何工作的,因爲它從來沒有明確地設置孩子? – Chris 2009-06-02 14:21:24

+0

構造函數本身通過迭代「children」參數,它是(幕後)迭代器遍歷xml ... – 2009-06-02 14:26:47

1

好吧,我沒有嘗試過這一點(沒有時間到現在),但我想應該差不多工作...

public class ErrorType 
{ 
    List<ErrorType> _childErrors; 

    public String Name { get; set; } 
    public bool Ignore { get; set; } 

    public List<ErrorType> ChildErrors { get; protected set; } 

    public static ErrorType Parse(XElement element) 
    { 
     return new ErrorType 
     { 
      Name = element.Name.LocalName, 
      Ignore = (bool) element.Attribute("Ignore"), 
      ChildErrors = element.Elements() 
           .Select(x => Parse(x)) 
           .ToList() 
     }; 
    } 
} 

public class ErrorList 
{ 
    public List<ErrorType> ChildErrors { get; protected set; } 

    public static ErrorList Parse(XElement element) 
    { 
     return new ErrorList { ChildErrors = element.Elements() 
           .Select(x => ErrorType.Parse(x)) 
           .ToList() }; 
    } 
}