new file: doxmind.py new file: doxml.py new file: example.png new file: test.xmind new file: test/test1.xml new file: test/test2.xml new file: xmind2case.py
178 lines
4.0 KiB
Python
178 lines
4.0 KiB
Python
# -*- 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
|
|
|