• [原创]从Confluence获取html table并将其序列化为C#类文件的工具


    公司项目的游戏数据模型文档写在Confluence上,由于在项目初期模型变动比较频繁,手工去将文档中最新的模型结构同步到代码中比较费时费力,而且还很容易出错,于是写了一个小工具来自动化这个同步更新模型到代码中的工作。

    如下是一个野怪的数据模型文档:

    最终在Unity的C#代码中它会是这个形式:

     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class MonsterData
     5 {
     6     public    int         monsterId;                        //人物id
     7     public    string      name;                             //怪物名称
     8     public    int         hp;                               //怪物最大生命值
     9     public    int         dodgeRate;                        //躲闪几率
    10     public    int         hitRate;                          //命中几率
    11     public    int         critHitRate;                      //暴击几率
    12     public    string      description;                      //描述
    13     public    int         exp;                              //经验
    14     public    int         atk;                              //攻击
    15     public    int         def;                              //防御
    16     public    string      imageName;                        //怪物图片的名字
    17     public    int         coins;                            //击杀怪物获得的金币数
    18     public    int         isBoss;                           //是否是Boss
    19 }

    我们需要的就是将图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 scriptmodify wiki page confluence programmatically.这样,第一个问题就解决了。

    这里插一句,我在开始的时候不知道有这个Remote API,所以尝试过不用他来实现获取Confluence的页面内容,能够访问到对应的页面,可是一直拿不到想要的html内容,不知道是什么问题,后来因为知道了Remote API,也没再继续尝试自己去获取了,有时间再研究以下。

    对于第二个问题

    解析html可以用python的库beautifulsoup来实现。关于beautifulsoup你可以看这里。这个beautifulsoup不仅名字好看,功能也异常强大。

    好了,解决问题的思路确定了,下面我们可以动手来实现这个工具了。以下便是我实现的代码,python写的不多,所以代码可能比较丑,见谅:)

      1 #!/usr/bin/python
      2 
      3 from bs4 import BeautifulSoup
      4 
      5 #for change encoding
      6 import sys
      7 
      8 #for login in confluence
      9 import xmlrpclib
     10 
     11 import os
     12 
     13 def mkdir(path):
     14  
     15     path = path.strip()
     16 
     17     path = path.rstrip("\")
     18  
     19     isExists = os.path.exists(path)
     20  
     21     if not isExists:
     22         print path + ' create successfully!'
     23         os.makedirs(path)
     24         return True
     25     else:
     26         print path + ' exists!'
     27         return False
     28  
     29 def makeTableContentList(table):
     30     result = []
     31     allrows = table.findAll('tr')
     32     rowIndex = 0
     33     for row in allrows:
     34         result.append([])
     35         #exclude the strike one
     36         if row.findAll('s'):    
     37             continue
     38 
     39         allcols = row.findAll('td')
     40         #print "rowIndex = ",rowIndex
     41         #print "allcols = ",allcols
     42 
     43         for col in allcols:
     44             #print "col",col
     45             thestrings = [unicode(s) for s in col.findAll(text=True)]
     46             thetext = ''.join(thestrings)
     47 
     48             result[-1].append(thetext)
     49         rowIndex += 1
     50     return result
     51 
     52 def makeFile(tableContentList):
     53 
     54     className = tableContentList[0][0]
     55 
     56     outputFile = file("output/" + className + ".cs","w")
     57     
     58     #start to write file
     59 
     60     #write header
     61     outputFile.write("using UnityEngine;
    ")
     62     outputFile.write("using System.Collections;
    
    ")
     63     outputFile.write("public class " + className + "
    {
    ")
     64 
     65     #write members
     66     rowCounter = 0
     67     for row in tableContentList:
     68         if row and rowCounter > 0:  #rowCounter == 0 is className
     69 
     70             #--------format---------
     71             beginSpaces = "    public    "
     72             typeString = "{:<12}".format(row[0])
     73             memberName = "{:<30}".format(row[1] + ";")
     74             comments = ""
     75 
     76             if len(row[2]) > 1:
     77                 comments = "    //" + row[2]  
     78             
     79             s = beginSpaces + typeString + memberName + comments + "
    "
     80 
     81             outputFile.write(s)
     82 
     83         rowCounter += 1
     84 
     85     #write tail
     86     outputFile.write("}
    ")
     87 
     88     outputFile.close()
     89 
     90 def setDefaultEncodingUTF8():
     91     reload(sys)
     92     sys.setdefaultencoding('utf-8')
     93 
     94 def loadConfluencePage(pageID):
     95 
     96     # login Confluence
     97     CONFLUENCE_URL = "http://192.168.1.119:8090/rpc/xmlrpc" 
     98     CONFLUENCE_USER_NAME = "userName"   # use your Confluence user Name
     99     CONFLUENCE_PASSWORD = "password"    # use your Confluence password
    100 
    101     # get this from the page url while editing
    102     # e.g. ../editpage.action?pageId=132350005 <-- here
    103     #PAGE_ID = "4686604" 
    104 
    105     client = xmlrpclib.Server(CONFLUENCE_URL, verbose = 0)
    106     auth_token = client.confluence2.login(CONFLUENCE_USER_NAME, CONFLUENCE_PASSWORD)
    107     page = client.confluence2.getPage(auth_token, pageID)
    108 
    109     htmlContent = page['content']
    110 
    111     client.confluence2.logout(auth_token)
    112  
    113     return htmlContent
    114 
    115 def main():
    116 
    117     #change Encoding to UTF8
    118     setDefaultEncodingUTF8()
    119 
    120     #make output directory
    121     mkdir(sys.path[0] + "/output")
    122 
    123     #there are two pages contain data model
    124     pageIDs = ("4686602","4686604")
    125 
    126     for pageID in pageIDs:
    127 
    128         print "Make data in page with id: ",pageID
    129 
    130         htmlContent = loadConfluencePage(pageID)
    131     
    132         soup = BeautifulSoup(htmlContent)
    133         #print soup.prettify()
    134 
    135         tables = soup.findAll('table')
    136 
    137         for table in tables:
    138             #print table
    139             result = makeTableContentList(table)
    140             makeFile(result)
    141             #print "result = "
    142             #print result
    143 
    144     print "Make Over! Have a nice day!"
    145 
    146 if __name__ == "__main__":
    147     main()

    OK,就到这里,希望大家喜欢:)

    转载请注明出处,谢谢:)

  • 相关阅读:
    JMeter学习-027-JMeter参数文件(脚本分发)路径问题:jmeter.threads.JMeterThread: Test failed! java.lang.IllegalArgumentException: File distributed.csv must exist and be readable解决方法
    JMeter学习-026-JMeter 分布式(远程)参数化测试实例
    JMeter学习-025-JMeter 命令行(非GUI)模式详解(三)-测试图形化 HTML 报表(dashboard)生成
    JMeter学习-024-JMeter 命令行(非GUI)模式详解(二)-执行代理设置
    JMeter学习-023-JMeter 命令行(非GUI)模式详解(一)-执行、输出结果及日志、简单分布执行脚本
    JMeter学习-022-JMeter 分布式测试(性能测试大并发、远程启动解决方案)
    JMeter学习-021-JMeter 定时器(Synchronizing Timer)之集合点应用
    JMeter学习-020-JMeter 监听器之【聚合报告】错误率、吞吐量、传输速率实例计算
    Selenium2学习-038-firefox、webdriver版本不对称问题解决:org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055
    JMeter学习-019-JMeter 监听器之【聚合报告】界面字段解析及计算方法概要说明
  • 原文地址:https://www.cnblogs.com/flyFreeZn/p/3860848.html
Copyright © 2020-2023  润新知