ASP.NET MVC 解析模板生成静态页一(RazorEngine)
简述
Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项。在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目。
我们在很多项目开发中会常常用到页面静态化,页面静态化有许多方式,最常见的就是类似很多PHP CMS种使用的 标签替换的方式(如:帝国CMS、EcShop等),还有很多都是伪静态,伪静态我们就不做过多解释,通过路由或Url重写来实现就可以了。Razor为我们提供了更加方便的模板解析方式,任何东西都是两方面的,技术也是如此,Razor解析模板虽然更加方便、简洁,但是对于模板制作人员来说也是有一定的技术要求,或者对于开发一套模板制作功能来说,考虑的要更多一些。我们不再去探究这些问题,我们更注重哪种技术更容易、更方便、更好的满足我们项目的需求。
如何使用RazorEngine
今天来简单介绍一下如何使用RazorEngine解析模板生成静态页面,RazorEngine它是基于微软的Razor之上,包装而成的一个可以独立使用的模板引擎。也就是说,保留了Razor的模板功能,但是使得Razor脱离于Asp.net MVC,能够在其它应用环境下使用,项目地址:https://github.com/Antaris/RazorEngine
首先我们去codeplex上下两个需要的dll http://razorengine.codeplex.com

看到网上很多介绍RazorEngine的基础用法的,讲解的都比较详细,对于RazorEngine运行原理很清晰,我们在这里就不重复介绍了。写这篇文章是对于很多新手同学来说比较喜欢“拿来主义”,基本的用法原理都能看懂,但是如何应用到项目中还是有些不是很清晰,我们只讲讲如何在项目中运用。
本文分为两部分:第一个部分,基本的单数据模型模板解析;第二部分,面向接口的多数据模型模板解析
第一个部分 基本的单数据模型模板解析
一、我们创建一个MVC项目,并且添加上面的两个DLL引用,然后我们新建一个简单的文章类
public class Articles
{
/// <summary>
/// 文章ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// 文章标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 文章内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; set; }
/// <summary>
/// 发布时间
/// </summary>
public DateTime CreateDate { get; set; }
}
二、我们新建一个Razor的Html模板
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>@Model.Title</title>
</head>
<body>
<h1>@Model.Title</h1>
<p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
<p>@Raw(Model.Content)</p>
</body>
</html>
说明:Model就是我们的文章实体类 在MVC的试图页cshtml中 我们一般都是在控制器里传递这个实体类 然后在视图页中 @model Models.Articles 来接收这个实体类 然后通过“@Model.”来输出内容,在Razor模板中是一样的,只是不用@model Models.Articles 来接收了,其它的语法跟在.cshtml试图页中是一样的,这么说多余了,因为写法不一样他就不是Razor了
三、我们写一个方法来获取模板页的Html代码
/// <summary>
/// 获取页面的Html代码
/// </summary>
/// <param name="url">模板页面路径</param>
/// <param name="encoding">页面编码</param>
/// <returns></returns>
public string GetHtml(string url, System.Text.Encoding encoding)
{
byte[] buf = new WebClient().DownloadData(url);
if (encoding != null) return encoding.GetString(buf);
string html = System.Text.Encoding.UTF8.GetString(buf);
encoding = GetEncoding(html);
if (encoding == null || encoding == System.Text.Encoding.UTF8) return html;
return encoding.GetString(buf);
} /// <summary>
/// 获取页面的编码
/// </summary>
/// <param name="html">Html源码</param>
/// <returns></returns>
public System.Text.Encoding GetEncoding(string html)
{
string pattern = @"(?i)\bcharset=(?<charset>[-a-zA-Z_0-9]+)";
string charset = Regex.Match(html, pattern).Groups["charset"].Value;
try { return System.Text.Encoding.GetEncoding(charset); }
catch (ArgumentException) { return null; }
}
四、我们写一个方法 用于生成Html静态页
/// <summary>
/// 创建静态文件
/// </summary>
/// <param name="result">Html代码</param>
/// <param name="createpath">生成路径</param>
/// <returns></returns>
public bool CreateFileHtmlByTemp(string result, string createpath)
{
if (!string.IsNullOrEmpty(result))
{
if (string.IsNullOrEmpty(createpath))
{
createpath = "/default.html";
}
string filepath = createpath.Substring(createpath.LastIndexOf(@"\"));
createpath = createpath.Substring(, createpath.LastIndexOf(@"\"));
if (!Directory.Exists(createpath))
{
Directory.CreateDirectory(createpath);
}
createpath = createpath + filepath;
try
{
FileStream fs2 = new FileStream(createpath, FileMode.Create);
StreamWriter sw = new StreamWriter(fs2, new System.Text.UTF8Encoding(false));//去除UTF-8 BOM
sw.Write(result);
sw.Close();
fs2.Close();
fs2.Dispose();
return true;
}
catch { return false; }
}
return false;
}
五、我们来写个方法调用静态模板,并且传递数据模型实体类 创建Html静态页
/// <summary>
/// 解析模板生成静态页
/// </summary>
/// <param name="temppath">模板地址</param>
/// <param name="path">静态页地址</param>
/// <param name="t">数据模型</param>
/// <returns></returns>
public bool CreateStaticPage(string temppath, string path, RazorEngineTemplates.Models.Articles t)
{
try
{
//获取模板Html
string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8); //初始化结果
string result = string.Empty; //解析模板生成静态页Html代码
result = Razor.Parse(TemplateContent, t); //创建静态文件
return CreateFileHtmlByTemp(result, path);
}
catch (Exception e)
{
throw e;
}
}
好了,大功告成,是不是很简单。

这里只是一个很简单的应用,没有读取数据,也没有列表,只有一个文章数据模型,下一部分我们将介绍 多模型模板解析,因为是多模型 所以 生成静态页面的时候 就不是传递一个具体模型实体类 我们会用到 反射,通过反射模型属性 获取数据,有不熟悉反射的可以提前研究一下,也可以直接看下一部分的反射代码也很简单的。
第二部分 面向接口的多数据模型模板解析
这一部分,我们介绍使用接口来解析模板,包括列表等多种模型解析,用到了Spring注入和反射还有接口等,有不熟悉的可以百度搜一下或者评论留言。
我们接着上面的示例,我们新建两个类库 一个是存放数据模型的 我们叫Domain;另外一个是接口和实现类的 我们叫Service,然后我们添加他们之间的引用

一、我们在Domain下创建几个测试类
Articles - 文章测试类
Company - 公司测试类
Column - 栏目测试类
TemplateView - 模型解析类(这个是不是比较弱智?我也没深入研究多个模型怎么反射出来 所以 我加了这么个算是公用的类 没有对应的数据表 只是解析模板的时候 作为中间件用用)
public class Articles
{
/// <summary>
/// 文章ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// 文章标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 文章内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; set; }
/// <summary>
/// 发布时间
/// </summary>
public DateTime CreateDate { get; set; }
}
public class Company
{
/// <summary>
/// 公司Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 公司名称
/// </summary>
public string CompanyName { get; set; }
/// <summary>
/// 公司电话
/// </summary>
public string CompanyTel { get; set; }
/// <summary>
/// 联系人
/// </summary>
public string ContectUser { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateDate { get; set; }
}
public class Column
{
/// <summary>
/// 栏目ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// 栏目名称
/// </summary>
public string Title { get; set; }
/// <summary>
/// 文章列表
/// </summary> public virtual ICollection<Articles> Articles { get; set; }
}
public class TemplateView
{
/// <summary>
/// ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; set; }
/// <summary>
/// 时间
/// </summary>
public DateTime CreateDate { get; set; }
/// <summary>
/// 公司名称
/// </summary>
public string CompanyName { get; set; }
/// <summary>
/// 公司电话
/// </summary>
public string CompanyTel { get; set; }
/// <summary>
/// 联系人
/// </summary>
public string ContectUser { get; set; }
/// <summary>
/// 文章列表
/// </summary>
public virtual ICollection<Articles> Articles { get; set; }
}
二、我们在Service下创建一个基础操作接口以及其实现类(里面的很多方法 比如:获取页面的Html代码、获取页面的编码以及创建静态文件等 是没有必要写在接口的 这个可以写到公用的类库里,因为这里就用到这么几个方法 所以我没有加公用类库 就直接写在这里面了)
/// <summary>
/// 基础操作接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IRepository<T> where T : class
{
/// <summary>
/// 解析模板生成静态页
/// </summary>
/// <param name="temppath">模板地址</param>
/// <param name="path">静态页地址</param>
/// <param name="t">数据模型</param>
/// <returns></returns>
bool CreateStaticPage(string temppath, string path, T t); /// <summary>
/// 获取页面的Html代码
/// </summary>
/// <param name="url">模板页面路径</param>
/// <param name="encoding">页面编码</param>
/// <returns></returns>
string GetHtml(string url, System.Text.Encoding encoding); /// <summary>
/// 获取页面的编码
/// </summary>
/// <param name="html">Html源码</param>
/// <returns></returns>
System.Text.Encoding GetEncoding(string html); /// <summary>
/// 创建静态文件
/// </summary>
/// <param name="result">Html代码</param>
/// <param name="createpath">生成路径</param>
/// <returns></returns>
bool CreateFileHtmlByTemp(string result, string createpath);
}
/// <summary>
/// 基础接口实现类
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class RepositoryBase<T> : IRepository<T> where T : class
{
/// <summary>
/// 解析模板生成静态页
/// </summary>
/// <param name="temppath">模板地址</param>
/// <param name="path">静态页地址</param>
/// <param name="t">数据模型</param>
/// <returns></returns>
public bool CreateStaticPage(string temppath, string path, T t)
{
try
{
//实例化模型
var Entity = new Domain.TemplateView(); //获取模板Html
string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);
//初始化结果
string result = ""; //反射赋值
Type typeT = t.GetType();
Type typeEn = Entity.GetType(); System.Reflection.PropertyInfo[] propertyinfosT = typeT.GetProperties(); foreach (System.Reflection.PropertyInfo propertyinfoT in propertyinfosT)
{
System.Reflection.PropertyInfo propertyinfoEn = typeEn.GetProperty(propertyinfoT.Name);
if (propertyinfoEn != null && propertyinfoT.GetValue(t, null) != null)
{
propertyinfoEn.SetValue(Entity, propertyinfoT.GetValue(t, null), null);
}
} //很多时候 我们并没有创建复杂的主外键关系 例如栏目下的文章 我们仅仅是在文章表中添加了一个所属栏目ID的字段
//并没有创建关联 这种情况下 我们直接获取栏目的时候 是获取不到文章列表的
//包括很多自定义的模型和字段 比如 文章的内容 可能不跟文章一个表 而是一个单独的大数据字段表 这种情况下 我们的
//TemplateView.Content就需要单独获取一下另一个数据模型里的 这个文章的内容 这种时候 我们可以在这里重新给他赋值 //如 传入的模型是 文章
//if(t is Domain.Articles)
//{
// Entity.Content= 查询大数据字段表中这篇文章的内容; //} result = Razor.Parse(TemplateContent, Entity); return CreateFileHtmlByTemp(result, path);
}
catch (Exception e)
{
throw e;
}
} /// <summary>
/// 获取页面的Html代码
/// </summary>
/// <param name="url">模板页面路径</param>
/// <param name="encoding">页面编码</param>
/// <returns></returns>
public string GetHtml(string url, System.Text.Encoding encoding)
{
byte[] buf = new WebClient().DownloadData(url);
if (encoding != null) return encoding.GetString(buf);
string html = System.Text.Encoding.UTF8.GetString(buf);
encoding = GetEncoding(html);
if (encoding == null || encoding == System.Text.Encoding.UTF8) return html;
return encoding.GetString(buf);
} /// <summary>
/// 获取页面的编码
/// </summary>
/// <param name="html">Html源码</param>
/// <returns></returns>
public System.Text.Encoding GetEncoding(string html)
{
string pattern = @"(?i)\bcharset=(?<charset>[-a-zA-Z_0-9]+)";
string charset = Regex.Match(html, pattern).Groups["charset"].Value;
try { return System.Text.Encoding.GetEncoding(charset); }
catch (ArgumentException) { return null; }
} /// <summary>
/// 创建静态文件
/// </summary>
/// <param name="result">Html代码</param>
/// <param name="createpath">生成路径</param>
/// <returns></returns>
public bool CreateFileHtmlByTemp(string result, string createpath)
{
if (!string.IsNullOrEmpty(result))
{
if (string.IsNullOrEmpty(createpath))
{
createpath = "/default.html";
}
string filepath = createpath.Substring(createpath.LastIndexOf(@"\"));
createpath = createpath.Substring(, createpath.LastIndexOf(@"\"));
if (!Directory.Exists(createpath))
{
Directory.CreateDirectory(createpath);
}
createpath = createpath + filepath;
try
{
FileStream fs2 = new FileStream(createpath, FileMode.Create);
StreamWriter sw = new StreamWriter(fs2, new System.Text.UTF8Encoding(false));//去除UTF-8 BOM
sw.Write(result);
sw.Close();
fs2.Close();
fs2.Dispose();
return true;
}
catch { return false; }
}
return false;
}
}
三、我们分别创建 文章管理、公司管理、栏目管理的接口和实现类 并且他们都集成基础操作
/// <summary>
/// 文章管理
/// </summary>
public interface IArticleManage:IRepository<Domain.Articles>
{
}
public class ArticleManage:RepositoryBase<Domain.Articles>,IArticleManage
{
} /// <summary>
/// 公司管理
/// </summary>
public interface ICompanyManage:IRepository<Domain.Company>
{
}
public class CompanyManage:RepositoryBase<Domain.Company>,ICompanyManage
{
} //栏目管理
public interface IColumnManage:IRepository<Domain.Column>
{
}
public class ColumnManage:RepositoryBase<Domain.Column>,IColumnManage
{
}
四、注入Xml
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<description>Spring注入Service,容器指向本层层封装的接口</description>
<object id="Service.ArticleManage" type="Service.ArticleManage,Service" singleton="false">
</object>
<object id="Service.ColumnManage" type="Service.ColumnManage,Service" singleton="false">
</object>
<object id="Service.CompanyManage" type="Service.CompanyManage,Service" singleton="false">
</object>
</objects>
五、我们分别初始化一个文章类、一个公司类(没有管理数据表,它下面没有文章列表 栏目模型我就不初始化了,怎么输出列表 大家可以参考下 栏目模板)
public class HomeController : Controller
{
/// <summary>
/// 声明一下注入接口
/// </summary>
public IArticleManage ArticleManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ArticleManage") as IArticleManage;
public ICompanyManage CompanyManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.CompanyManage") as ICompanyManage;
public IColumnManage ColumnManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.ColumnManage") as IColumnManage; public ActionResult Index()
{
//初始化一个文章数据模型
var entityArticle = new Domain.Articles() { Id = , Title = "这里是文章标题", Content = "<span style=\"color:red;\">这里是文章内容</span>", Author = "张三", CreateDate = DateTime.Now }; //初始化一个公司数据模型
var entityCompany = new Domain.Company() { Id = , CompanyName = "这里是公司名称", CompanyTel = "公司电话", ContectUser = "张三", CreateDate = DateTime.Now }; //调用方法生成静态页面
ArticleManage.CreateStaticPage(Server.MapPath("/Templates/Temp_article.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "1.html"), entityArticle);
CompanyManage.CreateStaticPage(Server.MapPath("/Templates/Temp_company.html"), Server.MapPath("/Pages/news/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "2.html"), entityCompany); return View();
} public ActionResult About()
{
ViewBag.Message = "Your application description page."; return View();
} public ActionResult Contact()
{
ViewBag.Message = "Your contact page."; return View();
} }
六、这是测试的简单的文章模板、公司模板和栏目模板

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>@Model.Title</title>
</head>
<body>
<h1>@Model.Title</h1>
<p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
<p>@Raw(Model.Content)</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<p>公司名称:@Model.CompanyName</p>
<p>公司电话:@Model.CompanyTel</p>
<p>联系人:@Model.ContectUser</p>
<p>创建时间:@Model.CreateDate</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<p>栏目标题: @Model.Title</p>
<p>
文章列表
<ul>
@foreach(var item in @Model.Articles)
{
<li>
<a href="">
<span>@item.Title</span>
<span>@item.Author</span>
<span>@item.CreateDate</span>
</a>
</li>
}
</ul>
</p>
</body>
</html>
我们运行一下,大功告成~~~


怎么排序?怎么获取前几条?怎么格式化日期时间?怎么分页?
这可是Razor啊,这都不需要再多讲了吧,简单一说,如果你传入数据前没有事先排序或者获取前几条,这些操作要做模板里操作 那跟在.cshtml里基本是一样的
@foreach(var item in @Model.ListColumn)
{ <div >
@if (@item.LinkUrl==null)
{
<ul>
@foreach(var article in @item.COM_ARTICLE.Take().OrderByDescending(p=>p.UpDateDate))
{ <li>
<a href="@article.LinkUrl" class="gd-a">
<div>@article.Title</div></a>
</li>
}
</ul>
}
else
{ }
</div>
}
应用还是很广泛的,而且解析代码相对于标签替换来说十分简洁、高效。有时间可以多研究研究,改天有空写一个模板替换标签的供大家参考一下。有人会说那我还得教前台制作Razor语法,这种说法我们没法去置评,标签替换你仍然要教他如何使用标签啊,所以是不是复杂并不是探究的主题,想要前台制作人员更方便的制作一套模板语法并不是主要因素,比如我们可以做一套方便的模板制作,用户点击一下就生成代码,或者直接做成可视化的,这可能让我们的程序员要耗费更多的精力,但是一劳永逸,标签替换方式你仍然要给前台制作人员一套标签规范和语法,况且后台解析异常的庞大和复杂。

还是那句老话,这篇文章仅仅是个人的一些理解和实现,可能中间会出现一些不合理的地方或是错误,请大家指正,我们共同学习研究。
Demo是用VS 2013写的
原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com
ASP.NET MVC 解析模板生成静态页一(RazorEngine)的更多相关文章
- NET MVC RazorEngine 解析模板生成静态页
ASP.NET MVC 解析模板生成静态页一(RazorEngine) 简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是 ...
- C# 用模板生成静态页
最近在研究静态页输出的问题,找了一些资料.做了一个简单的模板模式的静态输出 模板代码: <html xmlns="http://www.w3.org/1999/xhtml"& ...
- mvc分页生成静态页,mvc生成静态页
http://blog.csdn.net/xxj_jing/article/details/7899125 分页生成静态页 http://www.cnblogs.com/luanyilin/archi ...
- [Angularjs]asp.net mvc+angularjs+web api单页应用
写在前面 最近的工作一直在弄一些h5的单页应用,然后嵌入到app的webview中.之前一直在用angularjs+html+ashx的一套东西.实在是玩腻了.然后就尝试通过asp.net mvc的方 ...
- 基于PHP生成静态页的实现方法
t1.php 复制代码 代码如下: <?php// 方法一根据模版生成静态页面// replaceTemplateString函数用于替换模板中指定字符串function replaceTemp ...
- ThinkPHP生成静态页buildHtml方法
原来ThinkPHP自带了生成静态页的函数buildHtml,使用起来很方便!最新的手册里没写这个方法,向大家介绍一下. PHP 1 2 3 4 5 6 7 8 9 10 11 protect ...
- 生成静态页面的PHP类
生成静态页面的PHP类: 复制代码代码如下: <?php class html { var $dir; //dir for the htmls(without/) var $ ...
- tp 生成静态页
$this->fetch()返回的是html 可以直接写入到HTML文件内生成静态页
- dedesmc 手机端生成静态页
dedesmc 手机端生成静态页 1.首先下载插件,下载地址:https://pan.baidu.com/s/1Nfx_KBYuxRkZ7VzoPxy28g 密码:83x7 2.进入 dedecms ...
随机推荐
- JavaScript 事件管理
在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数.如下: this.foo = function(args,callbackFn) { //do som ...
- Web前端开发工程师养成计划【转载】
Web前端开发工程师养成计划(入门篇) 最原始的忠告:这个世界上有想法的人很多,但是有想法又能实现它的人太少! 首先要感谢伟大的Web2.0概念.产品概念.用户体验概念.jQuery插件,是它们在中国 ...
- upload4j安全、高效、易用的java http文件上传框架
简介 upload4j是一款轻量级http文件上传框架,使用简单,实现高效,功能专一,摆脱传统http文件上传框架的繁琐. upload4j的诞生并不是为了解决所有上传需求,而是专注于基础通用需求. ...
- 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...
- maven pom中的repository节点配置没有起作用
问题描述 昨天晚上想用spring boot快速搭建一个web开发的项目,就打开spring boot的doc,按照说明开始尝试.没想到出师未捷身先死,第一步就挂了. 以下是spring boot的配 ...
- sun.misc.BASE64Encoder找不到jar包的解决方法
1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...
- AngularJS表单验证实现方法详解
本文主要是通过源码实例和大家分享AngularJS中的表单验证相关知识,希望通过本文的分享,对大家学习AngularJS有所帮助. 1.常规表单验证: 2.AngularJs中提供的表单验证实例. 实 ...
- 轻量级前端MVVM框架avalon - 执行流程1
基本上确定了avalon的几个重要元素的关系: M,即model,一个普通的JS对象,可能是后台传过来的,也可能是直接从VM中拿到,即VM.$json.有关的这个$json的名字还在商讨 V,即Vie ...
- python3 字符串与列表常用功能
一.字符串常用功能 1. capitalize(),将字符串的首字母变成大写,其余全部置为小写:如果字符串中有多个单词,也只是将第一个单词的首字母置为大写:例: >>> name = ...
- 针对格式文件,Python读取一定大小的文件内容
由数据库导出的数据是格式化数据,如下所示,每两个<REC>之间的数据是一个记录的所有字段数据,如<TITLE>.<ABSTRACT>.<SUBJECT_COD ...