[原创]从Confluence获取html table并将其序列化为C#类文件的工具
公司项目的游戏数据模型文档写在Confluence上,由于在项目初期模型变动比较频繁,手工去将文档中最新的模型结构同步到代码中比较费时费力,而且还很容易出错,于是写了一个小工具来自动化这个同步更新模型到代码中的工作。
如下是一个野怪的数据模型文档:

最终在Unity的C#代码中它会是这个形式:
using UnityEngine;
using System.Collections; public class MonsterData
{
public int monsterId; //人物id
public string name; //怪物名称
public int hp; //怪物最大生命值
public int dodgeRate; //躲闪几率
public int hitRate; //命中几率
public int critHitRate; //暴击几率
public string description; //描述
public int exp; //经验
public int atk; //攻击
public int def; //防御
public string imageName; //怪物图片的名字
public int coins; //击杀怪物获得的金币数
public int isBoss; //是否是Boss
}
我们需要的就是将图1中得结构自动写成包含以上代码内容的C#文件。
下面说说具体的思路
首先,出于从实现难度和跨平台(前端开发用Mac后端开发用Windows)的考虑,我选择用Python来实现这个工具;
然后,分析这个问题可以知道,这个问题可以分解成2个小的问题来解决:
1.从Conflunce上获取对应文档页面的html table;
2.本地解析这个html table后,将其按照C#类的格式写入到文件中。
对于第一个问题
Confluence自带了Remote API,给开发者提供了非常方便的接口来访问或者更改指定页面的数据,点击这里可以查看它的官方文档。不过这个Remote API默认是关闭的,需要手工在设置里面开启,具体开启的步骤可以看这里,每个版本可能设置的布局略有不同,但是设置的东西都是一样的。
在python中可以使用xmlrpclib来调用Confluence的API。具体的实例可以看这两个链接:Updating a Confluence Wiki with a script和modify wiki page confluence programmatically.这样,第一个问题就解决了。
这里插一句,我在开始的时候不知道有这个Remote API,所以尝试过不用他来实现获取Confluence的页面内容,能够访问到对应的页面,可是一直拿不到想要的html内容,不知道是什么问题,后来因为知道了Remote API,也没再继续尝试自己去获取了,有时间再研究以下。
对于第二个问题
解析html可以用python的库beautifulsoup来实现。关于beautifulsoup你可以看这里。这个beautifulsoup不仅名字好看,功能也异常强大。
好了,解决问题的思路确定了,下面我们可以动手来实现这个工具了。以下便是我实现的代码,python写的不多,所以代码可能比较丑,见谅:)
#!/usr/bin/python from bs4 import BeautifulSoup #for change encoding
import sys #for login in confluence
import xmlrpclib import os def mkdir(path): path = path.strip() path = path.rstrip("\\") isExists = os.path.exists(path) if not isExists:
print path + ' create successfully!'
os.makedirs(path)
return True
else:
print path + ' exists!'
return False def makeTableContentList(table):
result = []
allrows = table.findAll('tr')
rowIndex = 0
for row in allrows:
result.append([])
#exclude the strike one
if row.findAll('s'):
continue allcols = row.findAll('td')
#print "rowIndex = ",rowIndex
#print "allcols = ",allcols for col in allcols:
#print "col",col
thestrings = [unicode(s) for s in col.findAll(text=True)]
thetext = ''.join(thestrings) result[-1].append(thetext)
rowIndex += 1
return result def makeFile(tableContentList): className = tableContentList[0][0] outputFile = file("output/" + className + ".cs","w") #start to write file #write header
outputFile.write("using UnityEngine;\n")
outputFile.write("using System.Collections;\n\n")
outputFile.write("public class " + className + "\n{\n") #write members
rowCounter = 0
for row in tableContentList:
if row and rowCounter > 0: #rowCounter == 0 is className #--------format---------
beginSpaces = " public "
typeString = "{:<12}".format(row[0])
memberName = "{:<30}".format(row[1] + ";")
comments = "" if len(row[2]) > 1:
comments = " //" + row[2] s = beginSpaces + typeString + memberName + comments + "\n" outputFile.write(s) rowCounter += 1 #write tail
outputFile.write("}\n") outputFile.close() def setDefaultEncodingUTF8():
reload(sys)
sys.setdefaultencoding('utf-8') def loadConfluencePage(pageID): # login Confluence
CONFLUENCE_URL = "http://192.168.1.119:8090/rpc/xmlrpc"
CONFLUENCE_USER_NAME = "userName" # use your Confluence user Name
CONFLUENCE_PASSWORD = "password" # use your Confluence password # get this from the page url while editing
# e.g. ../editpage.action?pageId=132350005 <-- here
#PAGE_ID = "4686604" client = xmlrpclib.Server(CONFLUENCE_URL, verbose = 0)
auth_token = client.confluence2.login(CONFLUENCE_USER_NAME, CONFLUENCE_PASSWORD)
page = client.confluence2.getPage(auth_token, pageID) htmlContent = page['content'] client.confluence2.logout(auth_token) return htmlContent def main(): #change Encoding to UTF8
setDefaultEncodingUTF8() #make output directory
mkdir(sys.path[0] + "/output") #there are two pages contain data model
pageIDs = ("","") for pageID in pageIDs: print "Make data in page with id: ",pageID htmlContent = loadConfluencePage(pageID) soup = BeautifulSoup(htmlContent)
#print soup.prettify() tables = soup.findAll('table') for table in tables:
#print table
result = makeTableContentList(table)
makeFile(result)
#print "result = "
#print result print "Make Over! Have a nice day!" if __name__ == "__main__":
main()
OK,就到这里,希望大家喜欢:)
转载请注明出处,谢谢:)
[原创]从Confluence获取html table并将其序列化为C#类文件的工具的更多相关文章
- Confluence 6 安装补丁类文件
Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中.这些问题将会使用 Class 类文件同时在官方 J ...
- mysql——获取所有table名和table字段名。
获取database所有table名: (参考:http://stackoverflow.com/questions/2780284/how-to-get-all-table-names-from-a ...
- js&jquery获取指定table指定行里面的内容
js&jquery获取指定table指定行里面的内容 CreateTime--2018年5月18日11:46:04 Author:Marydon 1.展示 代码展示 <table s ...
- 【原创】java 获取十个工作日之前或之后的日期(算当天)-完美解决-费元星
[原创]java 获取十个工作日之后的日期(算当天)-完美解决-费元星(仅考虑星期六星期天) /** * * 根据开始日期 ,需要的工作日天数 ,计算工作截止日期,并返回截止日期 * @param s ...
- 如果当前地图文档中有独立的Table,通过Engine如何获取该Table?
将IMap转为ITableCollection,通过ITableCollection.get_Table(int index);来获取该Table
- 一个简单的C#获取Session、设置Session类文件
一个简单的C#获取Session.设置Session类文件,本类主要实现大家最常用的两个功能: 1.GetSession(string name)根据session名获取session对象: 2.Se ...
- .NET C#利用反射获取类文件以及其中的方法&属性 并获取类及方法上的特性
了解C#特性类并声明我们自己的特性类[AttributeTest]代码如下 using System; namespace AttributeTest { /* 特性说明 特性本质是一个继承和使用了系 ...
- 获取指定开始行数$start,跨度$limit的文件内容
// 获取指定开始行数$page,跨度$step的文件内容 function getLine($file_name, $start, $limit) { $f = new SplFileObject( ...
- [原创作品] 对获取多层json值的封装
今天篇头不废话了,交流加群:164858883 在我们接收后端返回的json数据的时候,在数据缺失的时候,如果直接接收会导致致命错误的发生.可能有些同学会说通常都会有,不用判断直接获取也行.之前我也是 ...
随机推荐
- Use windows batch script to create menu
Background Recently, I find that we need to type some very long gradle commands to run build, chec ...
- 什么是spring?
一.对spring的理解. 1.Spring是实现了工厂模式的工厂类(什么是工厂类?简单的来说就是把需要的接口定义到一个类中,需要的时候不用新建,直接从这个类中调用该接口就可以了), 这个类的名字为B ...
- SpringMVC,MyBatis商品的增删改查
一.需求 商品的增删改查 二.工程结构 三.代码 1.Mapper层 (1) ItemsMapperCustom.java package com.tony.ssm.mapper; import ja ...
- TCoolMemo
我们先起个名字叫做TCoolMemo.以上篇已经讲了很多组件的技术,这里就只说出几个重点.其余不多说了. 首先,该Memo从CustomMemo继承,它有这样外观:属于平面的,边框是可以设置颜色的线, ...
- spring 定时任务的 执行时间设置规则(转)
spring 定时任务的 执行时间设置规则 单纯针对时间的设置规则org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运 ...
- linux下手动安装apache详解
引自:http://blog.chinaunix.net/uid-28458801-id-4211258.html error1:出现以下错误时候,需要下载安装apr configure: error ...
- 10个用于Web开发的最好 Python 框架
Python 是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准 库也是值得大家称赞的,Python甚至还 ...
- 车牌识别LPR(八)-- 字符识别
第八篇:字符识别 车牌定位.车牌倾斜校正.车牌字符分割都是为车牌字符识别做的前提工作,这些前提工作直接关系到车牌识别系统的性能.车牌字符识别是车牌识别系统的核心部分,车牌字符识别的准确率是衡量车牌识 ...
- 使用eclipse的快捷键自动生成的map或者reduce函数的参数中:“org.apache.hadoop.mapreduce.Reducer.Context context”
今天在测试mapreduce的程序时,就是简单的去重,对照课本上的程序和自己的程序,唯一不同的就是“org.apache.hadoop.mapreduce.Reducer.Context contex ...
- ios中addtarget
Target-action:目标-动作模式,它贯穿于iOS开发始终.但是对于初学者来说,还是被这种模式搞得一头雾水. 其实Target-action模式很简单,就是当某个事件发生时,调用那个对象中的那 ...