js格式化XML文本

  • Post author:
  • Post category:其他




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 版权协议,转载请附上原文出处链接和本声明。