JS格式化XML文本
调用:formatXml()
返回:{
zIndex: 1,// 层级
startText: ‘’,// 起始标签
endText: ‘’,// 结束标签
value: ’‘,// 展示内容
children: []// 子级
}
// xml格式化
formatXml(value) {
if (!value) return {}
return this.depthProcessingFn(value, 1)
},
// 深度处理
depthProcessingFn(value, zIndex, type) {
if (
!value.includes('<') ||
(value.slice(value.length - 2) === '/>' && value.indexOf(`<`) === value.lastIndexOf(`<`))||
value.indexOf(`</`) === value.lastIndexOf(`</`)
) {
return {
zIndex: type ? zIndex - 1 : zIndex,
startText: '',
endText: '',
value: value?.replace(/\s/g, ''),
children: []
}
}
const startIndex = value.indexOf('<')
const endIndex = value.indexOf('>')
const startLastIndex = value.lastIndexOf('<')
const endLastIndex = value.lastIndexOf('>')
const startName = value.slice(startIndex, endIndex + 1)
const startNameTag = startName.split(' ')[0]?.replace(/[\<\>]/g, '')
const endName = value.slice(startLastIndex, endLastIndex + 1)
const endNameTag = endName.split('/')[1]?.replace(/[\<\>]/g, '')
const startNameTagList = startName.split('=')
const subChildren = []
if (
startNameTag === endNameTag &&
value.indexOf(`</${startNameTag}>`) === value.lastIndexOf(`</${startNameTag}>`)
) {
if (startNameTagList.length > 1) {
startNameTagList.forEach((item, index) => {
if (index) {
const keyText = startNameTagList[index - 1].split(' ').pop()
const valueText = item.split(' ')
valueText.length > 1 && valueText.pop()
subChildren.push({
zIndex: zIndex + 1,
startText: '',
endText: '',
value: keyText + '=' + valueText.join(' '),
children: []
})
}
})
}
const newList = this.depthProcessingFn(
value.slice(endIndex + 1, startLastIndex).trim(),
type ? zIndex : zIndex + 1,
!type
)
return {
zIndex: type ? zIndex - 1 : zIndex,
startText: subChildren.length ? '<' + startNameTag : startName,
endText: endName,
value: value.indexOf(`</`) === value.lastIndexOf(`</`) ? value?.replace(/\s/g, '') : '',
children: [...subChildren, ...(Array.isArray(newList) ? newList : [newList])]
}
} else {
return this.brotherHandlingFn(value, zIndex, [])
}
},
// 同级处理
brotherHandlingFn(value, zIndex, valueList) {
if (!value) return valueList
const startIndex = value.indexOf('<')
const endIndex = value.indexOf('>')
const startName = value.slice(startIndex, endIndex)
const startNameTag = startName.split(' ')[0]?.replace(/[\<\>]/g, '')
const endLastIndex = value.indexOf(`</${startNameTag}>`)
const surplusIndex = endLastIndex + startNameTag.length + 3
const newValue = this.depthProcessingFn(value.slice(0, surplusIndex).trim(), zIndex + 1, true)
valueList.push(newValue)
return this.brotherHandlingFn(value.slice(surplusIndex).trim(), zIndex, valueList)
}
递归渲染组件:SubXml
<template>
<div>
<p v-if="xmlData.startText" :style="`padding-left:${xmlData.zIndex * 20}px;`">
{{ xmlData.startText }}
</p>
<p v-if="xmlData.value" :style="`padding-left:${xmlData.zIndex * 20}px;`">
{{ xmlData.value }}
</p>
<div v-if="!xmlData.value && xmlData.children && xmlData.children.length">
<SubXml v-for="(item, index) in xmlData.children" :key="index" :xml-data="item" />
</div>
<p v-if="xmlData.endText" :style="`padding-left:${xmlData.zIndex * 20}px;`">
{{ xmlData.endText }}
</p>
</div>
</template>
版权声明:本文为shikaixina原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。