如何提高加载xml文档的速度

时间:2012-11-28 16:00:23

标签: c# wpf mvvm linq-to-xml

我需要加载2种类型的xml文档;一个有50个子孩子,另一个有50个和800个子孩子。对于较小的文档,性能很好,并且在较大的文档中可以接受,直到子项数增加。 20k儿童* 50子儿=表现出色,20k儿童* 850子儿=表现缓慢。当它们不存在时,我如何跳过寻找额外的后代?我最初的尝试让我认为我需要为小型和大型文档分别提供类,方法,视图模型和视图。下面简要介绍一下我的代码。

public class MyItem
    {
        private string layout;
        private string column;
        private string columnSpan;
        private string row;
        private string rowSpan;
        private string background;

public MyItem(string layout, string column, string columnSpan, string row, string rowSpan, string background)
{
        Layout = layout;
        Column = column;
        ColumnSpan = columnSpan;
        Row = row;
        RowSpan = rowSpan;
        Background = background;
}

public string Layout
    {
        get { return this.layout; }
        set { this.layout = value; }
    }

(未显示 - Column,ColumnSpan,Row,RowSpan和Background,其处理方式与布局相同)

仅为此示例,下面仅显示6个子子节点,我正在寻找一种方法来加载仅包含前2个子子节点的xml文档。这样我可以使用小型或大型xml文档所需的任何加载方法。

internal class myDataSource
{
    //Loads (MyList) xml file 

    public static List<MyItem> Load(string MyListFilename)
    {

        var myfiles = XDocument.Load(MylistFilename).Descendants("item").Select(
            x => new MyItem(
                (string)x.Element("layout"),
                (string)x.Element("column"),
                (string)x.Element("columnSpan"),
                (string)x.Element("row"),
                (string)x.Element("rowSpan"),
                (string)x.Element("background")));

    return myfiles.ToList();
    }

public class MainViewModel : ViewModelBase
{

public void LoadMyList()
        {   

            this.myfiles = new ObservableCollection<MyItemViewModel>();

            List<MyItem> mybaseList = myDataSource.Load(MyListFilename);

            foreach (MyItem myitem in mybaseList)
            {
                this.myfiles.Add(new MyItemViewModel(myitem));
            }


            this.mycollectionView = (ICollectionView)CollectionViewSource.GetDefaultView(myfiles);
            if (this.mycollectionView == null)
                throw new NullReferenceException("mycollectionView");                
        }
}

 public class MyItemViewModel: ViewModelBase
{

    private Models.MyItem myitem;


    public MyItemViewModel(MyItem myitem)
    {
        if (myitem == null)
            throw new NullReferenceException("myitem");

        this.myitem = myitem;
    }      


    public string Layout
    {
        get
        {
            return this.myitem.Layout;
        }
        set
        {
            this.myitem.Layout = value;
            OnPropertyChanged("Layout");
        }
    }

(未显示 - Column,ColumnSpan,Row,RowSpan和Background,其处理方式与布局相同)

3 个答案:

答案 0 :(得分:1)

您可以遵循直接路径(即使用Descendants),而不是使用Elements吗?这是你不会扫描你知道没有物品的节点的唯一方法。

答案 1 :(得分:0)

我认为你可以做的一件事就是不要在Select上做一个toList并保持懒惰,而是返回一个Iterable,或者返回任何Select。(抱歉,我现在没有一个Windows框来测试这个)。当你做foreach时,你只会迭代一次(而不是现在两次)

答案 2 :(得分:0)

XDocument非常方便,但如果问题只是文件很大而你只需要扫描一次,那么XmlReader可能是更好的选择。它不读取整个文件,一次读取一个节点。您可以手动跳过您不感兴趣的部分。