python解析帆软cpt及frm文件(xml)获取源数据表及下游依赖表

#!/user/bin/evn python
import os,re,openpyxl
'''输入:帆软脚本文件路径输出:帆软文件检查结果Excel
'''
#获取来源表
def table_scan(sql_str):# remove the /* */ commentsq = re.sub(r"/\*[^*]*\*+(?:[^*/][^*]*\*+)*/", "", sql_str)# remove whole line -- and # commentslines = [line for line in q.splitlines() if not re.match("^\s*(--|#)", line)]# remove trailing -- and # commentsq = " ".join([re.split("--|#", line)[0] for line in lines])# split on blanks, parens and semicolonstokens = re.split(r"[\s)(;]+", q)# scan the tokens. if we see a FROM or JOIN, we set the get_next# flag, and grab the next one (unless it's SELECT).result = []get_next = Falsefor token in tokens:if get_next:if token.lower() not in ["", "select"]:#过滤掉因条件设置选择来源表而产生的脏数据非表名字符if '"+if' not in token and '"'not in token and '$if' not in token and '${if' not in token:result.append(token.replace('`',''))get_next = Falseget_next = token.lower() in ["from", "join"]#特殊单独情况处理:from后面来源表条件选择对应来源表,比如from ${if(XX,"来源表A","来源表B")}# print(result)if not result:tab_pat=re.compile(r'from.*?if\((.*?)\)',re.S)for i in re.findall(tab_pat,sql_str):temp_r=i.replace('"','').split(',')if '' not in temp_r and '/*' not in temp_r:result.append(temp_r[1].replace('`','').strip())result.append(temp_r[2].replace('`','').strip())return result#文件扫描,使用正则解析第一版,准确性不太高!
def file_scan(path):f_content=open(path,'r',encoding='utf-8').read()#1、数据集查询sqlgpat=re.compile('<TableDataMap>(.*?)</TableDataMap>',re.S)if_has_sqlg=re.findall(sqlgpat,f_content)rs_sql_list=[]if if_has_sqlg:#获取数据集名称以及数据集查询语句sqlspat=re.compile('<TableData name="(.*?)".*?<DatabaseName>\n<!\[CDATA\[(.*?)]]></DatabaseName>.*?<Query>\n<!\[CDATA\[(.*?)]]></Query>.*?</TableData>',re.S)rs1=re.findall(sqlspat,if_has_sqlg[0])for rsv in rs1:from_tables=[]if '"*/"' in rsv[1]:sql=rsv[1].split('*/')for ss in sql:from_tables.extend(table_scan(ss))else:from_tables.extend(table_scan(rsv[2]))rs_sql_list.append([rsv[0],rsv[1],rsv[2],set(from_tables)])# print(rsv[1])#2、js获取if_has_jsgpat=re.compile('<NameJavaScript name="(.*?)</NameJavaScript>',re.S)if_has_jsg=re.findall(if_has_jsgpat, f_content)rep_list = []  # 报表列表,去重if if_has_jsg:for jscon in if_has_jsg:# conturlpat=re.compile('<Content>.*?var\surl\s=.*?viewlet=(.*?.[cptfrm]{3})&.*?</Content>',re.S)conturlpat = re.compile('<Content>.*?viewlet=(.*?[cptfrm]{3})[&?].*?</Content>', re.S)if '<JavaScript class="com.fr.js.ReportletHyperlink">' in jscon:# rlpat=re.compile('<ReportletName extendParameters="true" showPI="true">\s<!\[CDATA\[(.*?)]]></ReportletName>',re.S)rlpat = re.compile( '<ReportletName .*?\[CDATA\[(.*?)]]></ReportletName>', re.S)rl=re.findall(rlpat,jscon)[0]# print(re.findall(rlpat,jscon))if rl not in rep_list:rep_list.append(rl)elif '<JavaScript class="com.fr.js.WebHyperlink">' in jscon:wlpat=re.compile('<URL>\s<!\[CDATA\[(.*?)]]></URL>',re.S)wl=re.findall(wlpat,jscon)[0]if wl not in rep_list:rep_list.append(wl)elif re.search(conturlpat,jscon):frl=re.findall(conturlpat,jscon)[0]print(frl)if not frl.startswith('/'):frl='/'+frlif frl not in rep_list:rep_list.append(frl)# elif '<JavaScript class="com.fr.js.JavaScriptImpl">'in jscon and('.cpt' in jscon or '.frm' in jscon) :#     print(jscon)if_has_cljpat=re.compile(r'<RHIframeSource.*?<Attr path="(.*?[cptfrm]{3}).*?</RHIframeSource>',re.S)f_has_clj=re.findall(if_has_cljpat,f_content)if f_has_clj:for v in f_has_clj:if v not in rep_list:rep_list.append(v)# print(rep_list)return rep_list,rs_sql_list#使用xml解析精准获取
def xml_scan(path):import xml.etree.ElementTree as ETtree = ET.parse(path)  # 打开xml文件dataset_iters = []  # 数据集名称,数据集数据库链接名,数据集查询语句,数据集来源sql表if list(tree.getroot().iter("TableDataMap")):# 数据集TableDataMap父节点table_map_content = list(tree.getroot().iter("TableDataMap"))[0]# 获取数据集查询名称dataset_iters_map = table_map_content.iter('TableData')for val in dataset_iters_map:# print('查询名称--',val.attrib.get("name"))dataset_name = val.attrib.get("name").strip()if len(list(val.iter("DatabaseName"))):# 帆软目前一个数据集查询框只能链接单个数据库,所以获取数据库链接名只有1个# print('查询数据库链接名--', list(val.iter("DatabaseName"))[0].text.strip())dataset_connect_name = list(val.iter("DatabaseName"))[0].text.strip()else:# print('查询数据库链接名--',None)dataset_connect_name = Noneif len(list(val.iter("Query"))):# 帆软目前一个数据集查询框只能链接单个数据库,所以获取数据库链接名只有1个,且只有一个sql查询窗口内容# print('查询数据查询语句--', list(val.iter("Query"))[0].text.strip())dataset_query = list(val.iter("Query"))[0].text.strip()from_tables = []if '"*/"' in dataset_query:sql = dataset_query.split('*/')for ss in sql:# print(ss)from_tables.extend(table_scan(ss))else:from_tables.extend(table_scan(dataset_query))else:# print('查询数据查询语句--', None)dataset_query = Nonefrom_tables=[]dataset_iters.append([dataset_name, dataset_connect_name, dataset_query,from_tables])urls = set()  # 报表全体下游调用URL集合js_contents = []  # js内容,内容清洗出来的URL,用于核对数据清洗是否准确# print(len(list(tree.iter("ReportletName"))))#js链接报表-网格报表-本地服务器local_url = [v.text.strip() for v in tree.iter("ReportletName")]if local_url:urls.update(local_url)# print(len(list(tree.iter("URL"))))  # js链接报表-网格报表-远程web链接web_url = [v.text.strip() for v in tree.iter("URL")]if web_url:urls.update(web_url)# print(len(list(val.iter("RHIframeSource"))))# js链接报表-tab框架挂载报表for v in tree.iter("RHIframeSource"):webframe_url = list(v.iter("Attr"))[0].attrib.get("path")# 去除URL尾巴参数if webframe_url and not webframe_url.endswith("frm") and not webframe_url.endswith("cpt"):rpat = re.compile(r'.*?[cptfrm]{3}', re.I)webframe_url = re.findall(rpat, webframe_url)[0]urls.update([webframe_url])elif webframe_url:urls.update([webframe_url])# print(len(list(val.iter("Content"))))for cv in list(tree.iter("Content")):contents = cv.texttemp_url = []# print(contents)http_ul_pat = re.compile(r'"(http.*?)"') #js内容里面挂载web超链接local_ul_pat = re.compile(r'viewlet=(.*?[cptfrm]{3})')#js内容里面挂载服务器本地绝对路径报表链接# print(re.findall(http_ul_pat,contents))# print(re.findall(local_ul_pat, contents))if re.findall(http_ul_pat, contents):urls.update(re.findall(http_ul_pat, contents))temp_url.extend(re.findall(http_ul_pat, contents))if re.findall(local_ul_pat, contents):# print(re.findall(local_ul_pat, contents))#处理挂载服务器本地链接路径,有些挂载绝对目录不规范a/b/c.cpt处理后输出/a/b/c.cptfor vl in re.findall(local_ul_pat, contents):if vl.startswith('/'):urls.update([vl])temp_url.append(vl)else:urls.update(['/'+vl])temp_url.append('/'+vl)js_contents.append([contents, temp_url])# print(js_contents)return dataset_iters,urls,js_contentsdef write_excel(list_tar,file_path):wb = openpyxl.Workbook()  # 新建工作簿sheet0=wb[wb.sheetnames[0]]sheet0.title=('引用报表列表')sheet1 = wb.create_sheet('来源mysql表')sheet2 = wb.create_sheet('帆软数据集查询及依赖明细')sheet3 = wb.create_sheet('帆软JS内容明细')sheet0['A1'] = '文件名'sheet0['B1'] = '依赖报表'sheet1['A1'] = '文件名'sheet1['B1'] = '依赖mysql表'sheet2['A1'] = '文件名'sheet2['B1'] = '数据集查询名称'sheet2['C1'] = '数据库链接名称'sheet2['D1'] = '数据集查询语句'sheet2['E1'] = '数据来源mysql表'sheet3['A1'] = '文件名'sheet3['B1'] = 'JS内容'sheet3['C1'] = 'JS解析URL'r=1k=1d=1x=1for index,item in enumerate(list_tar):print(('开始处理第 '+str(index+1)+' 个文件结果,共 '+str(len(list_tar))+' 个').center(50,'-'))# filename,dataset_iters, urls, js_contents# dataset_iters = []  # 数据集名称,数据集数据库链接名,数据集查询语句,数据集来源sql表target_file_name=item[0]cpt=item[2]sql=item[1]jsc=item[3]for id1,value in enumerate(sorted(cpt)):r=r+1sheet0.cell(row=r, column=1, value=target_file_name)sheet0.cell(row=r, column=2, value=value)sql_set=set()for id1,val in enumerate(sql):k = k + 1sql_set.update(val[3])sheet2.cell(row=k, column=1, value=target_file_name)sheet2.cell(row=k, column=2, value=val[0])sheet2.cell(row=k, column=3, value=val[1])sheet2.cell(row=k, column=4, value=val[2])sheet2.cell(row=k, column=5, value='\n'.join(val[3]))for id1,value in enumerate(sorted(sql_set)):d = d + 1sheet1.cell(row=d, column=1, value=target_file_name)sheet1.cell(row=d, column=2, value=value)for id1, value in enumerate(sorted(jsc)):if value[0] or value[1]:x = x +1sheet3.cell(row=x, column=1, value=target_file_name)sheet3.cell(row=x, column=2, value=value[0])sheet3.cell(row=x, column=3, value='\n'.join(value[1]))wb.save(file_path)wb.close() # excel使用完成需要关闭,否则会报错def main_scan(fr_path,result_path):rs_list=[]file_list=[]file_name=[]for dirpath, dirnames, filenames in os.walk(fr_path):for file in filenames:file_list.append(os.path.join(dirpath,file))file_name.append(os.path.join(dirpath,file).replace(r'【清空前缀:本地机扫描文件夹绝对路径】','').replace('\\','/'))for index,file in enumerate(file_list):print(('正在扫描第 '+str(index+1)+' 个文件,共 '+str(len(file_list))+' 个文件').center(50,'-'))try:dataset_iters,urls,js_contents = xml_scan(file)rs_list.append([file_name[index],dataset_iters,urls,js_contents])except:print('【文件扫描失败】:',file)print('文件扫描完毕,正在写入Excel'.ljust(50,'-'))write_excel(rs_list, result_path)if __name__ == '__main__':#帆软扫描文件夹绝对路径fr_path=r'【本地机扫描文件夹绝对路径】'#帆软扫描结果文件绝对路径result_path=r'【本地机结果路径】\scaning_result.xlsx'main_scan(fr_path, result_path)

扫描文件夹:

运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/74744.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Java+Swing实现超级玛丽游戏

基于JavaSwing实现超级玛丽游戏 一、系统介绍二、功能展示三、其他系统 一、系统介绍 超级玛丽小游戏的JAVA程序&#xff0c;进入游戏后首先按空格键开始&#xff0c;利用方向键来控制的马里奥的移动&#xff0c;同时检测马里奥与场景中的障碍物和敌人的碰撞&#xff0c;并判断…

2023年电赛E题报告模板(K210版)--可直接使用

任务 图1 任务内容 要求 图2 基本要求内容 图3 发挥部分内容 说明 图4 说明内容 评分标准 图5 评分内容 正文 &#xff08;部分&#xff09; 摘要 本文使用K210芯片设计了一个运动目标控制与自动追踪系统。系统包括使用深度学习进行识别激光位置&#xff0c;其中红色激…

论文代码学习—HiFi-GAN(4)——模型训练函数train文件具体解析

文章目录 引言正文模型训练代码整体训练过程具体训练细节具体运行流程 多GPU编程main函数&#xff08;通用代码&#xff09;完整代码 总结引用 引言 这里翻译了HiFi-GAN这篇论文的具体内容&#xff0c;具体链接。这篇文章还是学到了很多东西&#xff0c;从整体上说&#xff0c…

数据分析基础-Excel图表的美化操作(按照教程一步步操作)

一、原始数据 包含月份和对应的销量和产量。 时间销量产量1月60722月38673月28344月58685月67596月72357月61428月24319月556710月243511月122112月2645 二、原始的图表设计-采用Excel自带模板 三、优化思路 1、删除多余元素 2、弱化次要元素 对于可以弱化的元素&#xff0c…

VMware vSphere整体解决方案及实验拓扑

VMware vSphere整体解决方案及实验拓扑 VMware vSphere完整的解决方案 VMware vSphere有两个核心组件&#xff1a;ESXI&#xff0c;vCenter。ESXI实现的是单机虚拟化&#xff0c;而vCenter实现集群虚拟化&#xff0c;把所有的ESXI统一进行管理。当然了&#xff0c;要想是实现…

构建vue项目配置和环境配置

目录 1、环境变量process.env配置2、vue package.json多环境配置vue-cli-service serve其他用法vue-cli-service build其他用法vue-cli-service inspect其他用法3、vue导出webpack配置4、配置打包压缩图片文件5、打包去掉多余css(由于依赖问题暂时未实现)6、打包去除console.…

SW - 装配图用的组合零件的制作步骤

文章目录 SW - 装配图用的组合零件的制作步骤概述笔记END SW - 装配图用的组合零件的制作步骤 概述 一套相关零件做好后, 需要做装配体, 将零件都装上, 看看是否有纰漏. 如果不做总装图, 真不放心. 万一废了, 耽误的时间大把的. 做总装图的时间比做零件的2个星期比起来, 代价…

打印Winform控件实现简陋版的分页打印(C#)

本文的代码可以从这里获取&#xff1a;winformDemo.rar 张祥裕/分享的资源名称 - Gitee.com 作者的水平有限&#xff0c;如有错误&#xff0c;望指正。 为了简单起见&#xff0c;纸张大小&#xff0c;打印机等信息按照默认的来&#xff0c;本文的实现方案是&#xff1a;打印Pa…

使用正则表达式 移除 HTML 标签后得到字符串

需求分析 后台返回的数据是 这样式的 需要讲html 标签替换 high_light_text: "<span stylecolor:red>OPPO</span> <span stylecolor:red>OPPO</span> 白色 01"使用正则表达式 function stripHTMLTags(htmlString) {return htmlString.rep…

vue中各种混淆用法汇总

✨在生成、导出、导入、使用 Vue 组件的时候&#xff0c;像我这种新手就会常常被位于不同文件的 new Vue() 、 export default{} 搞得晕头转向。本文对常见用法汇总区分 new Vue() &#x1f4a6;Vue()就是一个构造函数&#xff0c;new Vue()是创建一个 vue 实例。该实例是一个…

阿里云ssl免费数字证书快过期 如何更换

1.登陆阿里云 找到ssl 查看快过期的证书 数字证书管理服务-ssl证书 2.创建免费的证书&#xff0c;对应过期证书的域名 3.下载新证书 pem key放在本地 此处记录本地的下载路径 /Users/dorsey/Downloads/10791167_lzzabc.cn_nginx/lzzabc.cn.pem /Users/dorsey/Downloads/1…

初阶数据结构——二叉树题目

文章目录 一、单值二叉树二、检查两颗树是否相同三、另一棵树的子树四、二叉树的前序遍历五、对称二叉树 一、单值二叉树 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff…

Mapping温度分布验证选择数据记录仪时需要考虑的13件事

01 什么是温度分布验证&#xff1f; 温度分布验证是通过在规定的研究时间内测量定义区域内的多个点来确定特定温度控制环境或过程&#xff08;如冷冻柜、冰箱、培养箱、稳定室、仓库或高压灭菌器&#xff09;的温度分布的过程。温度分布验证的目标是确定每个测量点之间的差异&…

1.netty介绍

1.介绍 是JBOSS通过的java开源框架是异步的,基于事件驱动(点击一个按钮调用某个函数)的网络应用框架,高性能高可靠的网络IO程序基于TCP,面向客户端高并发应用/点对点大量数据持续传输的应用是NIO框架 (IO的一层层封装) TCP/IP->javaIO和网络编程–>NIO—>Netty 2.应用…

FFmepg视频解码

1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置&#xff0c;本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单&#xff0c;实际就4步&#xff1a; 打开媒体流获取…

Redis-1

Redis 理论部分 redis 速度快的原因 1、纯内存操作 2、单线程操作&#xff0c;避免了频繁的上下文切换和资源争用问题&#xff0c;多线程需要占用更多的 CPU 资源 3、采用了非阻塞 I/O 多路复用机制 4、提供了非常高效的数据结构&#xff0c;例如双向链表、压缩页表和跳跃…

idea模块的pom.xml被划横线,不识别的解决办法

目录 问题&#xff1a; 解决办法&#xff1a; 1.打开设置 2. 取消勾选 3.点击确认 4.解决 问题提出&#xff1a; 写shi山的过程中&#xff0c;给模块取错名字了&#xff0c;改名的时候不知道点到了什么&#xff0c;一个模块的pom.xml变成灰色了&#xff0…

【Spring Cloud 四】Ribbon负载均衡

Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…

Vue没有node_modules怎么办

npm install 一下 然后再npm run serve 就可以运行了

isp调试工具环境搭建及其介绍!

一、isp调试环境搭建&#xff1a; 后期调试isp&#xff0c;是在rv1126提供的RKISP2.x Tuner工具上进行调试&#xff0c;所以我们大前提必须要把这个环境和一些操作先搞熟悉来&#xff0c;后面有一些专用术语&#xff0c;我们遇到了再去看&#xff0c;现在专门看一些专用术语&am…