服务器 频道

Web之页面处理-内容填充

  正常加载html后,根据ID获取A链接节点,并进行内容填充时,所需要的代码大致为:

  XmlDocument xDoc = new XmlDocument();

  try

  {

  xDoc.Load("xml文件路径");

  XmlNode xNode = xDoc.SelectSingleNode("xpath语法");

  if (xNode != null)

  {

  xNode.InnerText = "秋色园:cyqdata";//用户名填充

  if (xNode.Attributes["href"] == null)//用户名链接填充

  {

  XmlAttribute attr = xDoc.CreateAttribute("href");

  xNode.Attributes.Append(attr);

  }

  xNode.Attributes["href"].Value = "http://www.cyqdata.com/";

  }

  }

  使劲想啊:

  一个节点填充,需要写这么长的代码,开发起来那得是何等相当的吃力?

  对于Xml操作赋值,还需要考虑使用:,来解析复杂内容。

  如果没有一个好的思路来简化这些代码,开发起来不仅吃力,写完后的代码叠起来都得好几本书那么厚。

  写的痛苦,看的难受,接手维护的还得赶往富士康接着跳。

  为解救世人的这些苦难,在好多个日日夜夜后,XmlHelper出世了,它的出现,将这种开发简化到难与想象的地步,大大节省了代码量及提高了开发速度。

  二:XmlHelper,秋色园镇山之宝

  上节示例中话说已完成了页面html的加载,接着将分到各ashx处理程序中实现内容填充。

  且看XmlHelper 出手,填充上面那用户名:

  方法一:public void Set(string id, SetType setType, params string[] values);

  Document.Set("labUserName", SetType.A, "秋色园:cyqdata", "http://www.cyqdata.com/");

  用此方法,就一行,够省了吧。

  介绍:

  此方法,仅用于对单个节点填充。而SetType带有很多html标签类型,可根据不同类型选择不同标签。

  同时此方法也有几个重载,详细使用,请先看CYQ.Data API文档,后续再写教程文章,敬请关注。

  当然了,很多时候,值并不是固定的,通常是从数据库读取的较多,为了更好的和CYQ.Data下的MAction系列更好的结合,使出更简洁的用法,终于推出另一个方法:

  方法二:

  public void LoadData(MDataRow row);

  public void SetFor(string id, SetType setType, params string[] values);

  看看:两个方法配合,如何节源节流,先上图:

  上图,有用户的博客标题和博客简介,还有用户简介,这些都得读数据库,代码如何?

  Document.LoadData(DomainUser);

  Document.SetFor(IDKey.labSpaceName, forAdmin ? SetType.InnerText : SetType.InnerXml);

  Document.SetFor(IDKey.labSpaceIntro, forAdmin ? SetType.InnerText : SetType.InnerXml);

  if (!forAdmin)

  {

  Document.SetFor(IDKey.labCustomCss);

  }

  这是秋色园中使用的代码,用户前台和后台,加了点小分支。

  说明:

  SetFor是如何从DomainUser(即MDataRow)中取数据的呢?关键还是约定的ID。

  如labSpaceName,默认会读MDataRow中SpaceName字段的值,通过约定,内部最后再调用Set方法实现。

  从上面两个方法看出,最终,还是只针对一个节点进行填充。

  实际上,页面内容,多数是一个列表循环填充出来的。

  再上一个很传统的列表循环图:

  如果按传统的思路开发,应该将产生以下形式的代码:

  using (MAction action = new MAction(TableNames.Blog_Content))

  {

  MDataTable table = action.Select();//取得表

  XmlNode tableNode=Document.GetByID("tableID");//拿出table节点

  XmlNode child = tableNode.ChildNodes[0].Clone();//复制一份要循环的tr节点。

  tableNode.RemoveAll();//清除所有子节点

  foreach (MDataRow row in table)//循环行

  {

  XmlNode newTrNode = child.Clone();//复制行一份

  newTrNode.InnerText=row.Get(Content.Title);

  //然后赋第二个值。。第三个值...此处省略27个了

  tableNode.AppendChild(newTrNode);//加载行

  }

  }

  很勉强的挤出了以上一堆的代码,还是用上了CYQ.Data的MAction才能这么省。

  要是用其它框架写代码,那代码不还得往下排着走,试试CYQ.Data,有杀错不放过。

  不过,写多了,还是觉得很不可思议。

  其循环时,处理属性节点较多时,一个循环,那个代码写起来就得上百行了。

  你的天啊我的天,再写多几个循环,痛苦莫过于想跳楼还得排队买票再排队那个那个...

  为了将世人解救的更彻底些,怀胎十日后终于又生下了一个方法...

  方法三:

  public void LoadData(MDataTable table);

  public void SetForeach(string id, SetType setType, params object[] formatValues);

  介绍:

  看着熟悉吧:Set、SetFor、SetForeach,一看就是一个家族的。

  少说多做,看下SetForeach如何简化:

  using (MAction action = new MAction(CustomTable.ArticleView))

  {

  Document.LoadData(action.Select());

  Document.SetForeach("tableID", "

  • {2}", Users.UserName, Content.ID, Content.Title);

     

      }

      看,看,看,知道有多省了吧。

      不过情况往往是复杂的,在循环的过程中,多数情况需要二次处理?咋整?

      这个在秋色园里当然会出现,比如分页控件的样式,就是一种情况。

      为此,增加一个事件,Document_OnForeach(string text, object[] values, int row)

      且看用法:

      using (MAction action = new MAction(CustomTable.ArticleView))

      {

      Document.LoadData(action.Select());

      Document.OnForeach+=new XmlHelper.SetForeachEventHandler(Document_OnForeach);

      Document.SetForeach("tableID", "

  • {2}", Users.UserName, Content.ID, Content.Title);

     

      }

      string Document_OnForeach(string text, object[] values, int row)

      {

      //text就是被循环的标签内容

      //values就是row的值

      //row就是循环到第几行了

      //最后,爱咋处理就咋处理,反正最后 return text;

      }

  • 0
    相关文章