How Simple Object, 简称HSO, 是本人(How Qimiu)自创的一种语法简单的纯文本数据格式。
HSO致力于阅读简单和使用简单这两个目标。
本项目提供:
-
本 README:对其语法的介绍
-
HowSimpleObjectTool:一个有一定便利性的语法分析工具(C#)。
-
Notepad++ UDL Xml:适用于Notepad++的文件高亮设置(自定义语言格式文件,从Notepad++的语言->自定义语言格式可导入之)
HSO的语法吸收了现代编程语言和数据格式的一些特点,它有两个子类别,它们分别是"独立HSO"和"HSO数组"。
HSO只有一个基本数据类型——字符串,和两个高级数据类型——数组(内容是字符串)、字典(键为不包括特殊字符的字符串、内容是字符串的字典),如你所见,这二者都是集合。在一个How Simple Object中,只会包含这三种数据类型的实例,字符串会以键值对的方式存放,集合会以一种摊开的方式存放,因此数据看起来简单易懂——除非撰写数据文件的人不愿以容易观看的方式存放数据。
另外,HSO的数据项称作 How Simple Item (简称HSI)。
独立HSO的存放方式即是各个数据的简单组合,不需要额外的分隔符将整个内容包括起来。独立HSO具有十分简单的语法格式:
简单数据,先书写键(或者称作变量名),然后是等号,接着书写一个由引号包括的内容,最后以分号结束。
MyData1="This is a String";
数组,每个数组项目以键开始,然后是+=
号,然后是一条引号包括的内容,作为数组的元素之一,然后以分号结束。若希望为数组添加下一条数据,需要再写一次数组的键,然后是+=
号,然后是下一个数组元素,以分号结束。
这种访问方式就像使用某种重载了操作符的集合一样。
数组的每一条数据都是这样摊开存放在,将HSO从文件中解析为数组后,数组将保存文件中的顺序,建议同一个数组的所有数据条目都相邻存放。
MyAry+="My str1";
MyAry+="Her str2";
MyAry+="Our str3";
字典,每个字典以键开始,然后是点号.
,在点号后面写字典的某项数据的键,然后是=
号,之后写这个键对应的内容,然后以分号结束,同样,以引号包括。
本"宽泛HSO标准"允许键的重复,如果您希望更加严格,可以规定自己的标准,诸如"严格HSO标准 Choking Version"什么的。
如果您希望向字典添加更多的键值对,保持变量键(是指向这个字典的键,而不是字典内部的键)不变,用新的字典内容键、内容来建立新的一行数据。
这种访问方式就像Java,C#等语言访问内部变量一样。
MyDict1.firstname="Nya";
MyDict1.lastname="Err";
MyDict1.telephone="110-111222";
数据项目要求:变量名和字典的键皆大小写敏感。同时,变量名和字典的键都必须保证不包含换行、空格、标点、分隔符这几种特殊符号。需要点明的是,不允许的"标点、分隔符"是仅限Unicode 0~127 (即ASCII内的)范围内的标点和分隔符(另:下划线被视作字符,而不是特殊符号)。(可参考 Unicode表格 ,或者直接参考 Unicode 标准- 字符0~127 )
HSO没有规定文件的编码,你可以使用中文、日文、emoji等等不算在上述限制内的符号(从emoji等符号的角度来说,允许特殊符号)作为变量名。
空格(包括换行等空白字符)不能出现在键内部,但是允许出现在不同的部分之间。例如下面的示例是合法的HSO文件:
MyName = "How";
FontFamily += "SimSun";FontFamily += "FangSong";
FontFamily
+= "KaiTi";
Skill.Paint="lv.1";
Skill
.
Sport
=
"lv.0"
;
字符串的内容要求:有几个特殊字符不允许直接出现在文件的字符串中——他们是换行、双引号"
、反斜杠\
,为了保存这些数据,应该使用转义字符:
字符名称(程序中) | 转义写法(文件中) |
---|---|
换行(LF) | \n |
双引号 | \" |
单个反斜杠 | \\ |
其他特殊字符可以出现在文件的字符串中,但是为了可读性,应该以转义字符的方式记录他们,本标准支持这些符号的转义:
字符(程序中) | 转义写法(文件中) |
---|---|
回车(CR) | \r |
退格 | \b |
换页 | \f |
水平制表符 | \t |
垂直制表符 | \v |
响铃 | \a |
Null字符 | \0 |
HSO文件支持注释。支持//
和#
两种符号作为注释符号,注释符号直到行尾均被视作注释内容,//
后的注释将被直接忽视,#
后的注释根据用户的选择,可以忽视,也可以读入程序,这可以被作为一种元数据,为程序提供HSO对象以外的信息。本标准不规定#
后的注释应该具有什么意义,您可以基于此制定自己的标准。
注释看起来就是这个样子:
//这是必然会被忽视的注释
#对于此注释,用户可以选择读取之,也可以像斜杠注释一样直接忽视。
MyData="abc";
注释内容会被完全忽视,注释末尾的换行会被保留下来,这相当于注释可以被放在任何可以放换行的地方。就像下面这样:
MyData
//夹杂在中间的注释
="abc";
独立HSO文件
按照上述规则,将各项数据挨个写在文件中即成为了一个HSO文件。例如下面的小区信息:
Area="China";
小区名称="新兴花园小区";
楼栋+="1栋";
楼栋+="2栋";
楼栋+="3栋";
楼栋+="4栋";
住户通讯录.赵一="17111110111";
住户通讯录.钱久="18181818811";
住户通讯录.孙拾贰="138124789818";
文件后缀:建议将HSO文件保存为后缀为.hso
的文件。例如将上述文件保存为小区信息.hso
;
HSO数组是由多个HSO组成的数组。为了区分不同对象,每个HSO都应该被花括号{ }
包围。被花括号包围的多个HSO前后相继,即组成HSO数组。HSO数组不要求其中的每个HSO内部的键的一样的。
一个HSO数组如下所示
{
servicetype="illness";
name="li mouren";
age="20";
sex="女"
illness="感冒";
}
{
servicetype="illness";
name="shi li";
age="30";
sex="男"
illness="妇科疾病";
}
{
servicetype="examination";
name="qi er";
age="26";
sex="男";
action="体检";
}
文件后缀:建议将内容为HSO数组的数据保存为.hsa
或.hso
后缀的文件,其中 hsa=How Simple Array。例如将上述文件保存为医院事务20200509.hsa
或医院事务20200509.hso
;
使用两种后缀的哪一种需要根据实际情况定,比如,如果您的项目结构十分简单,不区分单独对象还是数组全部使用hso
可以得到便利,那么可选择之;如果您的项目需要读取各类数据,需要将单独hso和hso数组加以区分,那么以hsa
作为hso数组的结尾将更加方便。
另外,在文本内容的风格方面,由于HSO是为了易读而准备的数据格式,保存HSO数组时建议保持排版,上述示例数据已经践行了这个建议。
项目提供解析HSO文件(包括.hso
和.hsa
)用的工具,即 How Simple Object Tool。
目前该工具没有build成二进制文件,由于项目结构简单,目前只有3个.cs
文件,您可以直接下载并安放在您的项目中使用。今后若加以修改,也会尽量保持文件数量少的特色。
HSO Tool项目是用.Net Core开发的,开发时考虑了代码的兼容性,这些代码也可以直接用在.Net FrameWork中,其至少支持C#4.0。
将项目代码安置在您的项目中,使用HowSimpleObjectTool
命名空间下的类可以读取和生成HSO文件。
读取数据:使用静态类HowSimpleObjectBuilder
的方法可以读取数据,读取时要求使用者知道待读的数据是单独的HSO还是HSO数组,读取这两种文件需要使用不同的函数。默认提供读取文本、读取流对象StreamReader的文本的功能,如果您希望读其他模式的数据,可以实现IArticle
接口,实现其中的各类读取方法,传入相应方法中即可读取之。
读取数据中的注释:静态类HowSimpleObjectBuilder
提供的函数的重载支持读取井号注释的内容。本解析器进行过处理,如果您选择不读取井号注释,将不会对其注释内容进行任何储存操作,因此同等情况下效率高于等于读取注释的函数。
写入数据:使用静态类HowSimpleSerilizer
提供的函数可以写入HSO数据,默认提供写入到StringBuilder
、StreamWriter
的方法,如果您希望想其他地方写入数据,可以实现IPaper
接口,实现其中各类写入方法,传入相应方法中即可进行写入。目前不支持写入任何注释。目前写入数据时不会判断键和字典键的合法性,如果您向键中写入空格,那么数据将无法被正确读取。
使用数据:HSO在程序中以HowSimpleObject
的实例的形式出现,HSO数组的实例在程序中即是原生数组HowSimpleObject[]
。对于HSO,您可以直接使用MyHso["attrName"]
的方法得到HowSimpleObject的数据项(即HSI)。HSI允许你直接以简单数据、数组、字典的方式访问数据,即theItem1.Value
,theItem2["theKey"]
,theItem3[5]
,如果这个HSI的类型和你访问的方式不匹配,将抛出错误。每个HSI本质上是HSI的某个子类的实例——HowSimpleValueItem
、HowSimpleArrayItem
、HowSimpleDictionaryItem
中的一种,可以通过访问器ItemType
确定这个对象的类型。
本软件在大部分情况下都是可以免费使用的,具体许可类方式似MIT许可证。
本项目使用的许可证为在MIT许可证基础上,要求在用户将本软件用于商业用途时,如果本软件是商业用途的产品的主要内容,必须确保其客户知道本软件有免费获取的途径。
该许可证为本人进行修改而成的,称作MIT+CCUR。