Files
workflow2case/doxmind.py

178 lines
4.0 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
########### 本脚本用于解析 xmind, 并处理 xmind 导出的 xml 及其生成的 tree
import re
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import Element
from zipfile import ZipFile
content_xml = "content.xml" # 主要数据
comments_xml = "comments.xml"
styles_xml="styles.xml" # 样式
################################# xmind 提取 xml
def read_xmind(filename):
cache = {}
with ZipFile(filename) as xmind:
for f in xmind.namelist():
#print(f) # 所有的数据
for key in [content_xml, comments_xml, styles_xml]:
if f == key:
cache[key] = xmind.open(f).read().decode('utf-8')
xml=cache[content_xml]
stylexml=cache[styles_xml]
## 生成供调试
f=open(content_xml,"w")
f.writelines(xml)
f.close()
f=open(styles_xml,"w")
f.writelines(stylexml)
f.close()
return xml,stylexml
################################# xmind 的xml 转 list (非标准xml 先转 tree , 按tree处理)
def xml2list(xml,stylexml):
lists=[]
xml_content=xmind_content_to_etree(xml)
## 起始节点
start_node=xml_content.find('sheet').find('topic')
ids,title,styleids=get_ele_attr(start_node)
next_id=get_id_nextele(xml,ids)
lists.append([title,ids,next_id])
## 下级各个节点, 最后结构类似: [' Valid ', '76q1ecqiei4u494hnsu4a9cl0i', ['6690se63nn0agpf9u043icvmc4', '1je2u1g9ghg60eu0g41668akej'], type]
children_nodes=xml_content.find('sheet').find('topic').find('children').find('topics')
for children_node in children_nodes:
ids,title,styleids=get_ele_attr(children_node)
next_id=get_id_nextele(xml,ids)
types=styleid2type(styleids,stylexml) # 类型
lists.append([title,ids,next_id,types])
lists[0].append("start") ### 起始节点类型
return lists
# 转 etree
def xmind_content_to_etree(content):
xml_content = re.sub(r'\sxmlns="[^"]+"', '', content, count=1)
return ET.fromstring(xml_content.encode('utf-8'))
#### 获取节点的 id 和 title
def get_ele_attr(ele):
title=ele.find('title').text.strip()
ids=ele.attrib['id']
try:
styleids=ele.attrib['style-id']
except:
#print(u"style-id取值错误,id:",ids)
styleids=-1 # 默认的圆角矩形 没有这个key "org.xmind.topicShape.roundedRect"
return ids,title,styleids
##### 获取节点的 指向的下一个元素的 id
def get_id_nextele(xml,first_id):
xml_content=xmind_content_to_etree(xml)
relationships=xml_content.find('sheet').find('relationships')
## 遍历所有的 relationship
next_id=[]
for relationship in relationships:
the_id=relationship.attrib['end1']
if the_id==first_id:
next_id.append(relationship.attrib['end2']) # 可能有多个下一个
if next_id==[]:
next_id=[""] ## 为空则置一个空
return next_id
##### 根据 style id ,取得 style 样式,并进行转化 (非标准xml 先转 tree , 按tree处理)
def styleid2type(styleid,stylexml):
### 查找 shape-class
shape_class=""
types=""
if styleid==-1: # 默认的圆角矩形 没有这个key
shape_class="org.xmind.topicShape.roundedRect"
########################
stylexml_content=xmind_content_to_etree(stylexml)
style_nodes=stylexml_content.find('styles').findall('style')
for style_node in style_nodes:
ids=style_node.attrib['id']
if ids==styleid: ## 如果相同则查找对应的 shape-class
try:
shape_class=style_node.getchildren()[0].attrib['shape-class'] # 相当于 style_node.find['relationship-properties'][0].attrib['shape-class'],但这个方法报错
#print(shape_class)
except:
shape_class="org.xmind.topicShape.roundedRect"
#print(u"shape-class取值错误,styleid:",styleid)
### 转化
if shape_class=="org.xmind.topicShape.roundedRect":
types="sub"
if shape_class=="org.xmind.topicShape.circle":
types="select"
if shape_class=="org.xmind.topicShape.diamond":
types="func"
return types