2009-06-02 2 views
1

Недавно я задал вопрос о том, как Save a list with nested elements to XML, но теперь я пытаюсь написать загрузчик для класса и столкнулся с проблемами.Загрузка вложенного XML с использованием LiNQ

Я пытаюсь отменить ответ (спасибо 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() 
    { 

    } 
} 

Thankyou

ответ

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

+0

Сам конструктор создает дочерние элементы - путем итерации параметра «дети», который является (за кулисами) итератором над xml ... –

+0

Ahh У меня была слепота кода, и я не видел, чтобы вы передавали список в ctor в функции , Nice work mate спасибо – Chris

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() }; 
    } 
} 
+0

Спасибо за ответ Jon, но я не мог заставить его работать. Наверное, комбинация из вас мчалась и моя неспособность сшить то, что вы пытались сделать. – Chris

+0

Исправлено - должно быть хорошо. –