import JSZip from 'jszip' import xmlConvert from 'xml-js' // 解析.xmind文件 const parseXmindFile = file => { return new Promise((resolve, reject) => { JSZip.loadAsync(file).then( async zip => { try { let content = '' if (zip.files['content.json']) { let json = await zip.files['content.json'].async('string') content = transformXmind(json) } else if (zip.files['content.xml']) { let xml = await zip.files['content.xml'].async('string') let json = xmlConvert.xml2json(xml) content = transformOldXmind(json) } if (content) { resolve(content) } else { reject(new Error('解析失败')) } } catch (error) { reject(error) } }, e => { reject(e) } ) }) } // 转换xmind数据 const transformXmind = content => { let data = JSON.parse(content)[0] let nodeTree = data.rootTopic let newTree = {} let walk = (node, newNode) => { newNode.data = { // 节点内容 text: node.title } // 节点备注 if (node.notes) { newNode.data.note = (node.notes.realHTML || node.notes.plain).content } // 超链接 if (node.href && /^https?:\/\//.test(node.href)) { newNode.data.hyperlink = node.href } // 标签 if (node.labels && node.labels.length > 0) { newNode.data.tag = node.labels } // 子节点 newNode.children = [] if ( node.children && node.children.attached && node.children.attached.length > 0 ) { node.children.attached.forEach(item => { let newChild = {} newNode.children.push(newChild) walk(item, newChild) }) } } walk(nodeTree, newTree) return newTree } // 转换旧版xmind数据,xmind8 const transformOldXmind = content => { let data = JSON.parse(content) let elements = data.elements let root = null let getRoot = arr => { for (let i = 0; i < arr.length; i++) { if (!root && arr[i].name === 'topic') { root = arr[i] return } } arr.forEach(item => { getRoot(item.elements) }) } getRoot(elements) let newTree = {} let getItemByName = (arr, name) => { return arr.find(item => { return item.name === name }) } let walk = (node, newNode) => { let nodeElements = node.elements newNode.data = { // 节点内容 text: getItemByName(nodeElements, 'title').elements[0].text } try { // 节点备注 let notesElement = getItemByName(nodeElements, 'notes') if (notesElement) { newNode.data.note = notesElement.elements[0].elements[0].elements[0].text } } catch (error) { console.log(error) } try { // 超链接 if ( node.attributes && node.attributes['xlink:href'] && /^https?:\/\//.test(node.attributes['xlink:href']) ) { newNode.data.hyperlink = node.attributes['xlink:href'] } } catch (error) { console.log(error) } try { // 标签 let labelsElement = getItemByName(nodeElements, 'labels') if (labelsElement) { newNode.data.tag = labelsElement.elements.map(item => { return item.elements[0].text }) } } catch (error) { console.log(error) } // 子节点 newNode.children = [] let _children = getItemByName(nodeElements, 'children') if (_children && _children.elements && _children.elements.length > 0) { _children.elements.forEach(item => { if (item.name === 'topics') { item.elements.forEach(item2 => { let newChild = {} newNode.children.push(newChild) walk(item2, newChild) }) } else { let newChild = {} newNode.children.push(newChild) walk(item, newChild) } }) } } walk(root, newTree) return newTree } export default { parseXmindFile, transformXmind, transformOldXmind }