131 lines
4.3 KiB
JavaScript
131 lines
4.3 KiB
JavaScript
/**
|
||
* XML工具类,包含XML处理相关的方法
|
||
* @type {module}
|
||
*/
|
||
export class XmlUtils {
|
||
/**
|
||
* HTML转义
|
||
*/
|
||
static escapeHtml(unsafe) {
|
||
return unsafe
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """)
|
||
.replace(/'/g, "'");
|
||
}
|
||
|
||
/**
|
||
* 确保CommandList元素符合特定格式
|
||
*/
|
||
static ensureCommandListFormat(xmlDoc) {
|
||
// 如果没有rootElement,返回null
|
||
if (!xmlDoc) return null;
|
||
|
||
const rootElement = xmlDoc.documentElement;
|
||
|
||
// 查找或创建CommandList元素
|
||
let commandListElement = rootElement.querySelector('CommandList');
|
||
if (!commandListElement) {
|
||
commandListElement = xmlDoc.createElement('CommandList');
|
||
rootElement.appendChild(commandListElement);
|
||
}
|
||
|
||
return commandListElement;
|
||
}
|
||
|
||
/**
|
||
* 格式化XML
|
||
*/
|
||
static formatXml(xml) {
|
||
const parser = new DOMParser();
|
||
const xmlDoc = parser.parseFromString(xml, 'application/xml');
|
||
|
||
return XmlUtils.formatNode(xmlDoc, 0);
|
||
}
|
||
|
||
/**
|
||
* 递归处理XML节点
|
||
*/
|
||
static formatNode(node, level) {
|
||
if (!node) return '';
|
||
|
||
let result = '';
|
||
const indentStr = ' '.repeat(level);
|
||
|
||
// 处理不同类型的节点
|
||
switch (node.nodeType) {
|
||
case Node.DOCUMENT_NODE:
|
||
// 文档节点,处理子节点
|
||
result = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
||
for (let i = 0; i < node.childNodes.length; i++) {
|
||
result += XmlUtils.formatNode(node.childNodes[i], level);
|
||
}
|
||
break;
|
||
|
||
case Node.ELEMENT_NODE:
|
||
// 元素节点
|
||
result += indentStr + '<' + node.nodeName;
|
||
|
||
// 处理属性
|
||
for (let i = 0; i < node.attributes.length; i++) {
|
||
const attr = node.attributes[i];
|
||
result += ' ' + attr.name + '="' + attr.value + '"';
|
||
}
|
||
|
||
if (node.childNodes.length === 0) {
|
||
// 没有子节点,使用自闭合标签
|
||
result += ' />\n';
|
||
} else {
|
||
result += '>';
|
||
|
||
let hasElement = false;
|
||
let textContent = '';
|
||
|
||
// 检查是否只有文本内容
|
||
for (let i = 0; i < node.childNodes.length; i++) {
|
||
if (node.childNodes[i].nodeType === Node.ELEMENT_NODE) {
|
||
hasElement = true;
|
||
break;
|
||
} else if (node.childNodes[i].nodeType === Node.TEXT_NODE) {
|
||
textContent += node.childNodes[i].nodeValue;
|
||
}
|
||
}
|
||
|
||
if (hasElement) {
|
||
// 有元素子节点,换行并增加缩进
|
||
result += '\n';
|
||
for (let i = 0; i < node.childNodes.length; i++) {
|
||
result += XmlUtils.formatNode(node.childNodes[i], level + 1);
|
||
}
|
||
result += indentStr;
|
||
} else {
|
||
// 只有文本内容,不换行
|
||
result += textContent.trim();
|
||
}
|
||
|
||
result += '</' + node.nodeName + '>\n';
|
||
}
|
||
break;
|
||
|
||
case Node.TEXT_NODE:
|
||
// 文本节点,去除空白文本节点
|
||
const text = node.nodeValue.trim();
|
||
if (text) {
|
||
result += text;
|
||
}
|
||
break;
|
||
|
||
case Node.COMMENT_NODE:
|
||
// 注释节点
|
||
result += indentStr + '<!--' + node.nodeValue + '-->\n';
|
||
break;
|
||
|
||
default:
|
||
// 其他类型节点
|
||
break;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
}
|