我正在尝试通过2个级联循环从2个JSON对象构建xml文件。在第二个循环中,我找不到如何从上一个循环传递值:
在下面的示例中,我想将“ docnumber”值传递给我的第二个循环(通过GroupsACLJSON),以便从第二个JSON对象构建“ acl”节点,但要使用第二个JSON对象中的“ this.docnumber”父对象属性返回“ undefined”,从而导致一个空的“ acl”节点。
var documentsJSON = [{
"folder": "Enterprise1",
"extension": "DOCX",
"docnumber": "3912271",
"version": "1"
},
{
"folder": "Enterprise2",
"extension": "MSG",
"docnumber": "3912298",
"version": "1"
},
{
"folder": "Enterprise3",
"extension": "DOCX",
"docnumber": "3912692",
"version": "1"
}
]
var GroupsACLJSON = [{
"docNumber": "3912271",
"groupName": "group1"
},
{
"docNumber": "3912271",
"groupName": "group2"
},
{
"docNumber": "3912298",
"groupName": "group3"
},
{
"docNumber": "3912298",
"groupName": "group4"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var nodeArray = [];
var xmlObjectElement = {
node: function() {
for (var i = 0; i < documentsJSON.length; i++) {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
var nodeObject = {
location: documentsJSON[i].folder,
category: {
attribute: [{
'#text': documentsJSON[i].docnumber,
'@name': "Document Number"
}],
'@name': "ACME",
},
docnumber: documentsJSON[i].docnumber,
// loop through GroupsACLJSON to find if we have specific ACL groups for this document:
acl: function() {
var documentNumber = this.docnumber
console.log(this.docnumber);
var acl = [];
var aclObject = {};
for (var j = 0; j < GroupsACLJSON.length; j++) {
if (GroupsACLJSON[j].docNumber == documentNumber) {
aclObject = {
'@group': GroupsACLJSON[j].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
},
'@type': "document",
'@action': "create",
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
};
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));
这是我期望得到的输出:
<import>
<node type="document" action="create">
<location>Enterprise1</location>
<category name="ACME">
<attribute name="Document Number">3912271</attribute>
</category>
<docnumber>3912271</docnumber>
<acl group="group1" permissions="111111100" />
<acl group="group2" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise2</location>
<category name="ACME">
<attribute name="Document Number">3912298</attribute>
</category>
<docnumber>3912298</docnumber>
<acl group="group3" permissions="111111100" />
<acl group="group4" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise3</location>
<category name="ACME">
<attribute name="Document Number">3912692</attribute>
</category>
<docnumber>3912692</docnumber>
<acl/>
</node>
</import>
答案 0 :(得分:0)
您有几个未声明的变量,这些变量将在严格模式下运行时导致代码中断。
i
和j
都需要声明。例如let i = 0
。aclObject
。您需要添加一个var声明,例如const aclObject = { ... }
。修复这些问题后,至少可以轻松运行代码,至少可以轻松构建xmlObjectElement并执行有效的node()和acl()函数。
已更新
这不会解决xml-builder遍历对象和构建xml的方式,但是可以通过使用Array方法而不是for循环来改善您的功能。因此,您无需使用i
或j
并减少引入错误的机会。
例如,您可以使用.map()
轻松地替换两个循环。参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。
var xmlObjectElement = {
node: function () {
return documentsJSON.map((document) => {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
return {
location: document.folder,
category: {
attribute: [
{ '#text': document.docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
....
})
答案 1 :(得分:0)
按照nxSolari的建议,我使用2个函数而不是大对象和方法重新编写了代码,并获得了预期的结果。我仍然不了解代码如何通过对象和方法,但是这里是新的工作代码:
'use strict';
var documentsJSON = [{
"folder":"Enterprise1" ,
"extension":"DOCX" ,
"docnumber":"3912271" ,
"version":"1"
},
{
"folder":"Enterprise2" ,
"extension":"MSG" ,
"docnumber":"3912298" ,
"version":"1"
},
{
"folder":"Enterprise3" ,
"extension":"DOCX" ,
"docnumber":"3912692" ,
"version":"1"
}
]
var GroupsACLJSON = [{
"docNumber":"3912271" ,
"groupName":"group1"
},
{
"docNumber":"3912271" ,
"groupName":"group2"
},
{
"docNumber":"3912298" ,
"groupName":"group3"
},
{
"docNumber":"3912298" ,
"groupName":"group4"
},
{
"docNumber":"3912692" ,
"groupName":"group5"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var xmlObjectElement = {};
function buildACLnode(passedDoc, acls) {
var acl= [];
for (var jDoc = 0 ; jDoc < acls.length ; jDoc++) {
if (acls[jDoc].docNumber == passedDoc) {
var aclObject = {
'@group': acls[jDoc].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
}
function buildXML(documents) {
var nodeArray = [];
for (var iDoc = 0; iDoc < documents.length; iDoc++) {
var nodeObject = {
node: {
location: documentsJSON[iDoc].folder,
category: {
attribute: [
{ '#text': documentsJSON[iDoc].docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
acl: buildACLnode(documentsJSON[iDoc].docnumber, GroupsACLJSON),
'@type': "document",
'@action': "create",
}
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
xmlObjectElement = buildXML(documentsJSON);
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));