一个函数解决对html/xml的属性进行排序
低代码平台针对不同地市会创建不同的页面版本,有时要对比不同地市的差异,需要对比不同页面版本的xml配置项,无序的属性让对比起来比较吃力。 代码编辑器基于codeMirror,对比工具使用插件merge.js,美化插件使用js-beautify.js,由于没有提供属性排序能力,所以这里手动实现一下。
1. 问题
解决对两块html页面或者xml配置文件片段的对比,尤其是单行属性较长有横向滚动条时,先排一个顺序再对比会更加清晰直观。
2. 代码
/**
* 将 XML 文档中的属性按字母顺序排序。
*
* @param {string} xmlStr - 需要排序的 XML 字符串。
* @returns {string} 排序后的 XML 字符串。
*/
function sortXMLAttributes(xmlStr) {
// 将 XML 字符串解析为 XML 文档对象
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlStr, "text/xml");
/**
* 递归地将 XML 节点的属性按字母顺序排序。
*
* @param {Node} node - 需要排序的 XML 节点。
*/
function sortAttrs(node) {
if (node.attributes && node.attributes.length > 0) {
// 将属性的 NodeList 转换为数组,并按字母顺序排序
const attrs = Array.from(node.attributes);
attrs.sort((a, b) => a.name.localeCompare(b.name));
// 从节点中移除所有属性
while (node.attributes.length > 0) {
node.removeAttribute(node.attributes[0].name);
}
// 将排序后的属性添加回节点中
attrs.forEach(attr => {
node.setAttribute(attr.name, attr.value);
});
}
// 递归地对每个子节点的属性进行排序
for (let i = 0; i < node.childNodes.length; i++) {
sortAttrs(node.childNodes[i]);
}
}
// 对根节点的属性进行排序
sortAttrs(xmlDoc);
// 将 XML 文档序列化为字符串
const serializer = new XMLSerializer();
return serializer.serializeToString(xmlDoc);
}
使用
const xmlString = `
<root>
<item id="3" name="item3" class="def" />
<item data-option="456" id="1" name="item1" />
<item title="abc" id="2" name="item2" />
</root>
`;
console.log(sortXMLAttributes(xmlString));
打印信息
<root>
<item class="def" id="3" name="item3"/>
<item data-option="456" id="1" name="item1"/>
<item id="2" name="item2" title="abc"/>
</root>