【问题标题】:Load nested XML using LiNQ使用 LiNQ 加载嵌套的 XML
【发布时间】:2009-06-02 11:05:17
【问题描述】:

我最近问了一个关于如何Save a list with nested elements to 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()
    {

    }
}

谢谢

【问题讨论】:

    标签: c# .net xml linq-to-xml


    【解决方案1】:

    我得到了类似的东西:

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

    有什么用吗?

    【讨论】:

    • 这很好,谢谢。我不完全确定它是如何工作的,因为它从未明确设置孩子?
    • 构造函数本身创建子节点 - 通过迭代“children”参数,这是(在幕后)xml 上的迭代器...
    • 啊,我有代码失明,没有看到您将列表传递给函数中的 ctor。很好的工作伙伴,谢谢
    【解决方案2】:

    好的,我还没有尝试过(现在也没有时间),但我认为它应该很有效......

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

    【讨论】:

    • 感谢 Jon 的回复,但我无法正常工作。可能是你匆忙和我无法将你试图做的事情拼接在一起。
    猜你喜欢
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多