Commit 538dc862 by qlintonger xeno

feat: 使用LCS对比+123

parent a3e85107
......@@ -1533,6 +1533,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
......@@ -1962,6 +1975,20 @@
"node": ">=8"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
......@@ -2025,12 +2052,10 @@
"dev": true
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
......@@ -2043,6 +2068,18 @@
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es5-ext": {
"version": "0.10.64",
"resolved": "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.64.tgz",
......@@ -2288,15 +2325,21 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
......@@ -2305,6 +2348,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/git-raw-commits": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
......@@ -2350,11 +2406,12 @@
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
"get-intrinsic": "^1.1.3"
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
......@@ -2384,21 +2441,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
......@@ -2938,6 +2985,15 @@
"semver": "bin/semver"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/meow": {
"version": "12.1.1",
"resolved": "https://registry.npmmirror.com/meow/-/meow-12.1.1.tgz",
......
......@@ -9,7 +9,7 @@
<CEP>
<EFFECT EFFRG="001999"></EFFECT>
<TITLEC>发动机QEC拆卸(V2500-A5系列)</TITLEC>
<TITLE>Remove the Engine's QEC(V2500-A5 series)xxx</TITLE>
<TITLE>Remove the Engine's QEC(V2500-A5 series)XXXX</TITLE>
<TOPIC CK-LEVEL="C">
<TITLEC>飞机/发动机基本信息</TITLEC>
<TITLE>AIRCRAFT/ENGINE INFORMATION</TITLE>
......@@ -26,6 +26,32 @@
</NOTE>
<SIGNOFF/>
</STEP>
<STEP CK-LEVEL="C">
<EFFECT EFFRG="001999"></EFFECT>
<RECORD-LINE>
<PARAC>发动机序号</PARAC>
<PARA>Engine SN</PARA>
<RECORD></RECORD>
</RECORD-LINE>
<NOTE>
<PARAC>开始工作前请记录。</PARAC>
<PARA>Please record before starting work.</PARA>
</NOTE>
<SIGNOFF/>
</STEP>
<STEP CK-LEVEL="C">
<EFFECT EFFRG="001999"></EFFECT>
<RECORD-LINE>
<PARAC>发动机序号</PARAC>
<PARA>Engine SN</PARA>
<RECORD></RECORD>
</RECORD-LINE>
<NOTE>
<PARAC>开始工作前请记录。</PARAC>
<PARA>Please record before starting work.</PARA>
</NOTE>
<SIGNOFF/>
</STEP>
</TOPIC>
<TOPIC CK-LEVEL="C">
<TITLEC>工作准备</TITLEC>
......
......@@ -29,7 +29,8 @@ export class Processing {
hash: item.hash,
index: item.index,
chained: item.chained,
textContent: item.textContent
textContent: item.textContent,
node: item.node
})
if (item.children) {
resp.push(...this.flattenTree(item.children))
......@@ -55,27 +56,13 @@ export class Processing {
} {
const treeA = this.domParser.parseFromString(xmlStringOld, 'text/xml')
const treeB = this.domParser.parseFromString(xmlStringNew, 'text/xml')
const resultA = this.innerHandle(treeA.documentElement, bothHandledNode)
const resultB = this.innerHandle(treeB.documentElement, bothHandledNode)
const resultA = this.innerHandle(treeA.documentElement, bothHandledNode, contentHoldNode)
const resultB = this.innerHandle(treeB.documentElement, bothHandledNode, contentHoldNode)
treeA.documentElement.querySelectorAll(':not([data-key])').forEach((node) => node.remove())
treeB.documentElement.querySelectorAll(':not([data-key])').forEach((node) => node.remove())
// 扁平化所有节点
const resultAFlatted = this.flattenTree(resultA)
.filter((item) => {
return contentHoldNode.includes(item.label)
})
.map((item, index) => ({
...item,
index
}))
const resultBFlatted = this.flattenTree(resultB)
.filter((item) => {
return contentHoldNode.includes(item.label)
})
.map((item, index) => ({
...item,
index
}))
const results = dualCompare(resultAFlatted, resultBFlatted).filter((a) => a.type !== 'same')
......@@ -103,7 +90,8 @@ export class Processing {
// 处理 XML 字符串的方法,返回树形数据和 XML DOM 对象
processXML(
xmlContent: string,
handledNode: string[]
handledNode: string[],
contentHoldNode: string[]
): {
treeData: TreeRenderResult[]
xmlDOM: Document
......@@ -115,7 +103,7 @@ export class Processing {
const rootElement = parsedTree.documentElement
const result = {
// 调用 innerHandle 方法处理根元素,生成树形数据
treeData: this.innerHandle(rootElement, handledNode),
treeData: this.innerHandle(rootElement, handledNode, contentHoldNode),
// 返回解析后的 XML DOM 对象
xmlDOM: parsedTree
}
......@@ -129,7 +117,8 @@ export class Processing {
// 异步处理 XML 文件的方法,返回包含树形数据和 XML DOM 对象的 Promise
async processFile(
xmlFile: File,
handledNode: string[]
handledNode: string[],
contentHoldNode: string[]
): Promise<{
treeData: TreeRenderResult[]
xmlDOM: Document
......@@ -146,7 +135,7 @@ export class Processing {
const content = fr.result as string
try {
// 调用 processXML 方法处理读取的文件内容
const { treeData, xmlDOM, xmlContent } = this.processXML(content, handledNode)
const { treeData, xmlDOM, xmlContent } = this.processXML(content, handledNode, contentHoldNode)
// 解析成功,返回树形数据和 XML DOM 对象
resolve({ treeData, xmlDOM, xmlContent })
......@@ -165,7 +154,7 @@ export class Processing {
}
// 私有方法,用于递归处理单个 DOM 节点,生成树形数据
private innerHandle(domNode: Element, handledNode: string[]): TreeRenderResult[] {
private innerHandle(domNode: Element, handledNode: string[], contentHoldNode: string[]): TreeRenderResult[] {
let treeData: TreeRenderResult[] = []
// 生成唯一的 key
let targetKey = domNode.getAttribute('data-key')
......@@ -179,16 +168,18 @@ export class Processing {
children: [],
index: 0,
chained: [0],
hash: md5.hex(domNode.textContent! || ''),
textContent: domNode.textContent || ''
hash: contentHoldNode.includes(domNode.nodeName) ? md5.hex(domNode.textContent! || '') : md5(domNode.nodeName),
textContent: domNode.textContent || '',
node: domNode
}
// 为 DOM 节点设置 data-key 属性
domNode.setAttribute('data-key', targetKey)
domNode.setAttribute('data-w-e-type', domNode.nodeName)
domNode.setAttribute('data-indent-level', '0')
domNode.setAttribute('data-chained', treeItem.chained.join('$'))
domNode.setAttribute('data-hash', treeItem.hash)
// 递归处理子节点
treeItem.children = this.innerGroupHandle(domNode.children, handledNode, [0])
treeItem.children = this.innerGroupHandle(domNode.children, handledNode, [0], contentHoldNode)
// 将树形数据项添加到结果数组中
treeData.push(treeItem)
......@@ -196,7 +187,7 @@ export class Processing {
}
// 私有方法,用于递归处理一组 DOM 节点,生成树形数据
private innerGroupHandle(nodeSet: HTMLCollection, handledNode: string[], startChained: number[]): TreeRenderResult[] {
private innerGroupHandle(nodeSet: HTMLCollection, handledNode: string[], startChained: number[], contentHoldNode: string[]): TreeRenderResult[] {
let targetResult: TreeRenderResult[] = []
let realIndex = -1
// 遍历节点集合
......@@ -206,7 +197,7 @@ export class Processing {
if (!handledNode.includes(node.nodeName)) {
// 如果节点有子节点,递归处理子节点
if (node.children.length) {
targetResult.push(...this.innerGroupHandle(node.children, handledNode, startChained))
targetResult.push(...this.innerGroupHandle(node.children, handledNode, startChained, contentHoldNode))
}
continue
}
......@@ -222,17 +213,19 @@ export class Processing {
label: node.nodeName,
index: realIndex,
chained: [...startChained, realIndex],
hash: md5.hex(node.textContent! || ''),
textContent: node.textContent || ''
hash: contentHoldNode.includes(node.nodeName) ? md5.hex(node.textContent! || '') : md5(node.nodeName),
textContent: node.textContent || '',
node: node
}
// 为 DOM 节点设置 data-key 属性
node.setAttribute('data-key', targetKey)
node.setAttribute('data-w-e-type', node.nodeName)
node.setAttribute('data-indent-level', startChained.length.toString())
node.setAttribute('data-chained', treeItem.chained.join('$'))
node.setAttribute('data-hash', treeItem.hash)
// 如果节点有子节点,递归处理子节点
if (node.children.length > 0) {
treeItem.children = this.innerGroupHandle(node.children, handledNode, [...startChained, realIndex])
treeItem.children = this.innerGroupHandle(node.children, handledNode, [...startChained, realIndex], contentHoldNode)
}
// 将树形数据项添加到结果数组中
targetResult.push(treeItem)
......
......@@ -5,8 +5,6 @@ export function dualCompare(oldItems: TreeRenderResultFlatted[], newItems: TreeR
const oldItemsCount = oldItems.length
const newItemsCount = newItems.length
console.log('old and new', { oldItems, newItems })
const dp: number[][] = Array.from({ length: oldItemsCount + 1 }, () => Array(newItemsCount + 1).fill(0))
for (let i = 1; i <= oldItemsCount; i++) {
......
import { Processing } from '@/lib/XMLProcessor/src/core/Processing.ts'
import { Plugin, getCurrentInstance } from 'vue'
import { getCurrentInstance, Plugin } from 'vue'
import TextA from '@/assets/file/CES-QEC-V250-A.xml?raw'
import TextB from '@/assets/file/Trans-Convert.xml?raw'
import { nodeSet, contentHoldNode } from '@/configs/node.config'
import { contentHoldNode, nodeSet } from '@/configs/node.config'
const p = new Processing()
// @ts-ignore
......@@ -10,6 +10,11 @@ window.$p = function () {
let nodeV = p.dualCompareFromString(TextA, TextB, nodeSet, contentHoldNode)
console.log('v-h', nodeV)
}
// @ts-ignore
window.$ap = function() {
}
export const XMLProcessing: Plugin = function (app) {
app.provide('xmlProcessing', p)
}
......
......@@ -5,7 +5,8 @@ export type TreeRenderResult = {
hash: string,
index: number,
chained: number[],
textContent: string
textContent: string,
node: Element
}
export type TreeRenderResultFlatted = {
......@@ -14,7 +15,8 @@ export type TreeRenderResultFlatted = {
hash: string,
index: number,
chained: number[],
textContent: string
textContent: string,
node: Element
}
export type OldTreeModification = {
......
......@@ -73,7 +73,7 @@ export const onClickoutside = () => {
export const handleChange = (editor: IDomEditor) => {
if (editor.getHtml() == '<p><br></p>') return
const xmlProcessing = useXMLProcessing()
const res = xmlProcessing.processXML(editor.getHtml().replace(/<p><br><\/p>/g, ''), nodeSet)
const res = xmlProcessing.processXML(editor.getHtml().replace(/<p><br><\/p>/g, ''), nodeSet, contentHoldNode)
treeData.value = res.treeData
}
// 上传xml
......@@ -89,7 +89,7 @@ export const uploadXml = async () => {
const file = files[0]
const xmlProcessing = useXMLProcessing()
showLoading.value = true
const res = await xmlProcessing.processFile(file, nodeSet)
const res = await xmlProcessing.processFile(file, nodeSet, contentHoldNode)
showLoading.value = false
editorHtml.value = res.xmlContent
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment