如题:在TM软件设计中,我将用户聊天记录用XML形式保存如下
Message.Xml
<messages>
   <message xmlns="http://www.abc.com/xmtp" from="[email protected]" date="2009-6-2 14:17:19" id="b4a3b2f40906012317n19203c96p2b43ce4997df8c31">
      <subject>Test 0</subject>
      <body>Test 0</body>
   </message>
   <message xmlns="http://www.abc.com/xmtp" from="[email protected]" date="2009-6-2 14:17:19" id="b4a3b2f40906012317n19203c96p2b43ce4997df8c32">
      <subject>Test 1</subject>
      <body>Test 1</body>
   </message>
   <message xmlns="http://www.abc.com/xmtp" from="[email protected]" date="2009-6-2 14:17:19" id="b4a3b2f40906012317n19203c96p2b43ce4997df8c33">
      <subject>Test 2</subject>
      <body>Test 2</body>
   </message>
   <message xmlns="http://www.abc.com/xmtp" from="[email protected]" date="2009-6-2 14:17:19" id="b4a3b2f40906012317n19203c96p2b43ce4997df8c34">
      <subject>Test 3</subject>
      <body>Test 3</body>
   </message>
......
</messages>由于聊天记录相当庞大,需要一种可以动态加载数据并分页的方法。比如我设定每页10条记录,当我点选第一页时希望系统只读取前10条message记录,当点选第二页时读取11-20条message记录,系统动态读取message.xml文件,而非一次性全部加载message.xml文件,请问技术上如何处理?谢谢

解决方案 »

  1.   

    那就用最原始的分页方法:
    OleDbDataAdapter MyAdapter = new OleDbDataAdapter(strSel,MyConn); 
    MyAdapter.Fill(ds,StartIndex,PageSize,"Score"); 
      

  2.   

    完整代码:
    <% @ Page Language="C#" %> 
      <% @ Import Namespace="System.Data" %> 
      <% @ Import Namespace="System.Data.OleDb" %> 
      <Script Language="C#" Runat="Server"> 
      OleDbConnection MyConn; 
      int PageSize,RecordCount,PageCount,CurrentPage; 
      public void Page_Load(Object src,EventArgs e) 
      { 
       //设定PageSize 
       PageSize = 10; 
       
       //连接语句 
       string MyConnString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="+Server.MapPath(".")+"..\\DataBase\\db1.mdb;"; 
       MyConn = new OleDbConnection(MyConnString); 
       MyConn.Open(); 
       
       //第一次请求执行 
       if(!Page.IsPostBack) 
       { 
       ListBind(); 
       CurrentPage = 0; 
       ViewState["PageIndex"] = 0; 
       
       //计算总共有多少记录 
       RecordCount = CalculateRecord(); 
       lblRecordCount.Text = RecordCount.ToString(); 
       
       //计算总共有多少页 
       PageCount = RecordCount/PageSize; 
       lblPageCount.Text = PageCount.ToString(); 
       ViewState["PageCount"] = PageCount; 
       } 
      } 
      //计算总共有多少条记录 
      public int CalculateRecord() 
      { 
       int intCount; 
       string strCount = "select count(*) as co from Score"; 
       OleDbCommand MyComm = new OleDbCommand(strCount,MyConn); 
       OleDbDataReader dr = MyComm.ExecuteReader(); 
       if(dr.Read()) 
       { 
       intCount = Int32.Parse(dr["co"].ToString()); 
       } 
       else 
       { 
       intCount = 0; 
       } 
       dr.Close(); 
       return intCount; 
      } 
       
      ICollection CreateSource() 
      { 
       
       int StartIndex; 
       
       //设定导入的起终地址 
       StartIndex = CurrentPage*PageSize; 
       string strSel = "select * from Score"; 
       DataSet ds = new DataSet(); 
       
       OleDbDataAdapter MyAdapter = new OleDbDataAdapter(strSel,MyConn); 
       MyAdapter.Fill(ds,StartIndex,PageSize,"Score"); 
       
       return ds.Tables["Score"].DefaultView; 
      } 
      public void ListBind() 
      { 
       score.DataSource = CreateSource(); 
       score.DataBind(); 
       
       lbnNextPage.Enabled = true; 
       lbnPrevPage.Enabled = true; 
       if(CurrentPage==(PageCount-1)) lbnNextPage.Enabled = false; 
       if(CurrentPage==0) lbnPrevPage.Enabled = false; 
       lblCurrentPage.Text = (CurrentPage+1).ToString(); 
       
      } 
       
      public void Page_OnClick(Object sender,CommandEventArgs e) 
      { 
       CurrentPage = (int)ViewState["PageIndex"]; 
       PageCount = (int)ViewState["PageCount"]; 
       
       string cmd = e.CommandName; 
       //判断cmd,以判定翻页方向 
       switch(cmd) 
       { 
       case "next": 
       if(CurrentPage<(PageCount-1)) CurrentPage++; 
       break; 
       case "prev": 
       if(CurrentPage>0) CurrentPage--; 
       break; 
       } 
       
       ViewState["PageIndex"] = CurrentPage; 
       
       ListBind(); 
       
      } 
      </script> 
      <html> 
      <head> 
      <title></title> 
      </head> 
      <body> 
      <form runat="server"> 
      共有<asp:Label id="lblRecordCount" ForeColor="red" runat="server" />条记录  
      当前为<asp:Label id="lblCurrentPage" ForeColor="red" runat="server" />/<asp:Label id="lblPageCount" ForeColor="red" runat="server" />页  
       
      <asp:DataList id="score" runat="server" 
      HeaderStyle-BackColor="#aaaadd" 
      AlternatingItemStyle-BackColor="Gainsboro" 
      EditItemStyle-BackColor="yellow" 
      > 
       <ItemTemplate> 
       姓名:<%# DataBinder.Eval(Container.DataItem,"Name") %> 
       <asp:LinkButton id="btnSelect" Text="编辑" CommandName="edit" runat="server" /> 
       </ItemTemplate> 
      </asp:DataList> 
      <asp:LinkButton id="lbnPrevPage" Text="上一页" CommandName="prev" OnCommand="Page_OnClick" runat="server" /> 
      <asp:LinkButton id="lbnNextPage" Text="下一页" CommandName="next" OnCommand="Page_OnClick" runat="server" /> 
       
      </form> 
      </body> 
      </html> 
      

  3.   


    是Xml文件哦,不是数据库
      

  4.   

    当然首先第一步,需要把你的xml转换为一个DataTable了.(就是根据你的xml自己在内存中构造一个DataTable或者其他的类型的DataSet)
      

  5.   

    考虑到分页的方便性,还是一次性将xml文件读到内存中吧.当然最好理想的效果是用xmlReader(用xmlReader读xml实际上可以说是xml的流模式读取(省内存,不同于xmlDocument.load是将整个xml都先加载进来),想想DataReader,他们又类比性)只读取PageSize条记录了.(关于它的算法,你自己参考一个分页存储过程的算法吧.)
      

  6.   

    那就用XmlTextReader,
    read()
    一个节点一个节点地读,要的节点才读进来或者你看看用xmldocument的selectsinglenode/selectnodes利用xpath语法来读读看二.XPath路径匹配符号
     1.基本路径匹配说明
          / :   选择根节点,还可以表示路径,/A/B/C :表示匹配A节点的孙节点C   // : 匹配子元素,//A :匹配所有A元素,//A/B :匹配A中的所有B元素
          * : 通配符,表示所有元素 /A/* : 匹配A节点所有元素
         | : 或运算,路径的或运算,//A|//B :所有A和B元素
     
      [ 1 ] :选择第一个元素
      [ last() ] :最后一个元素
      [ number ]:指定具体的位置,/booklist/book[3] :匹配booklist中的第三个book元素
      [position()=number] :由数字指定第几个位置的元素
      [position()>number] :匹配位置大于指定数字的元素
     
      
     2.属性匹配说明:
      
       [ @id ]        :匹配有属性名"id"的元素
          [ @name ]     :匹配有属性名"name"的元素
          [ @* ]     : 匹配有属性的元素
          [ not@* ]  : 匹配没有属性的元素
          [ @id="name"] :匹配具有属性"id"为"name"元素, /booklist/book
          [@authorid="zuozhebianhao"]  3.XPath表达式用法拓展
     text()                                    选择当前节点    所有文本节点
        @name             选择当前节点    名为name的属性节点
        @*              选择当前节点    所有有属性的节点
        para[ 1 ]            选择当前节点    第一个para子节点
        para[ last() ]         选择当前节点    最后一个para子节点
       */para           选择当前节点    所有para孙节点
        / para / ch[ 5 ] / s[ 2 ]    选择para节点       第5个ch节点的第2个s节点
        ../@attr           选择当前节点      父节点的属性节点attr
        para[ @type="warning" ]    选择当前节点    所有属性"type"为"warning"
        chapter[ title ]                      选择当前节点    至少有一个title子元素的chapter节点
        para[@attr and @attr]      选择当前节点    有属性attr1和attr2的para元素
       
     .  表示:self.node()  选择当前节点
        
     ..   表示:parent.node()  选择当前父节点