从对象构建XML时如何自动为标签添加命名空间前缀?
如何让XML构建器自动为标签添加命名空间前缀?
我有如下JS对象:
{ myRoot: { $: { 'xmlns:abc': 'blahblah', }, one: 'a', two: 'b', three: 'c' } }
想要生成带有abc:前缀的XML,无需修改对象里的属性名,目标XML如下:
<abc:myRoot xmlns:abc='blahblah'> <abc:one>a</abc:one> <abc:two>b</abc:two> <abc:three>c</abc:three> </abc:myRoot>
之前尝试给Builder()构造函数传tagNameProcessor函数但没效果,现在只能手动给属性名加abc:前缀,请问该怎么解决?
解决方案(以xml2js库为例)
问题核心有两点:一是XML构建器不会默认将所有子标签归到声明的命名空间下(因为支持多命名空间场景);二是单独使用tagNameProcessor时,根标签的前缀需要单独配置,否则处理器无法作用于根标签。
直接上可用代码:
const { Builder } = require('xml2js'); const data = { myRoot: { $: { 'xmlns:abc': 'blahblah' }, one: 'a', two: 'b', three: 'c' } }; // 给所有子标签添加abc前缀的处理器 const addNamespacePrefix = (tagName) => `abc:${tagName}`; const builder = new Builder({ rootName: 'abc:myRoot', // 直接指定根标签带前缀 tagNameProcessor: addNamespacePrefix, renderOpts: { pretty: true, indent: ' ' } // 格式化输出XML }); // 传入myRoot下的内容(根标签已通过rootName指定) const xml = builder.buildObject(data.myRoot); console.log(xml);
为什么之前的tagNameProcessor无效?
多数XML构建器的tagNameProcessor不会自动处理根标签,根标签需要通过rootName参数单独配置。另外,构建器不会默认把所有子标签关联到声明的命名空间——这是设计逻辑,因为XML允许在同一文档中使用多个命名空间,构建器无法推断你想把所有标签都归到当前前缀下。
如果使用xmlbuilder2库,写法会更直观:
const { create } = require('xmlbuilder2'); const data = { myRoot: { $: { 'xmlns:abc': 'blahblah' }, one: 'a', two: 'b', three: 'c' } }; // 直接创建带命名空间的根标签 const xmlDoc = create().ele('abc:myRoot', data.myRoot.$); // 遍历子属性,逐个创建带前缀的子标签 Object.entries(data.myRoot).forEach(([key, value]) => { if (key !== '$') { xmlDoc.ele(`abc:${key}`).txt(value).up(); } }); // 生成格式化后的XML const finalXml = xmlDoc.end({ prettyPrint: true }); console.log(finalXml);
内容的提问来源于stack exchange,提问作者Jason Perrone
相关产品推荐
相关产品推荐

