json - 蒙哥错误: key $ must not start with '$' when store JSON object generated by xml2js module

标签 json xml node.js mongodb node-mongodb-native

各位

MongoDB db.version() is 3.0.5
mongodb package.json shows 2.0.42 version
xml2js package.json shows 0.4.9 version  

我已经用谷歌搜索了错误,并通读了所有现有问题,但似乎没有一个符合我的情况(jira issue 和 g oogle group discussions 等)。这可能与 mongodb 本地驱动程序(或 MongoDB 服务器版本)、xml2js 或其他东西有关。

我做了很多测试,确实找到了解决问题的方法,但我很想知道问题出在哪里。

我有一个执行以下操作的应用程序:

  1. 将 XForm (survey.xml) 上传到 ExpressJS
  2. 使用 xml2js 库将 XML 转换为 JSON 对象(示例如下)
  3. 遍历 2 中创建的 JSON 对象并删除不需要的字段(如下所示的代码片段)
  4. 使用mongodb native driver将3中修改后的JSON对象推送到MongoDB

第 4 步因错误而失败(显示在问题的标题中)。

  1. 有 2 个 JSON 对象,一个是调查表,包含 $ 键但是,在我将文档插入 mongodb 之前,我使用以下代码删除了 $ 键

    (function traverse(o) {
    for (var i in o) {
      if (o[i] !== null && typeof(o[i])=="object") {
          //going on step down in the object tree!!
        if(o[i].$) {
          var ref = "";
          if(o[i].$.ref) {
            ref = o[i].$.ref;
          } else if (o[i].$.nodeset) {
            ref = o[i].$.nodeset;
          }
          o[i].ref = ref;
          o[i].$ = undefined;
          var chunks = ref.split('/');
          o[i]['name'] = chunks[chunks.length - 1];
        }
        traverse(o[i]);
      }
    }
    })(body);
    
  2. 在将上面的输出添加到 MongoDB 之前,我用控制台记录了上面的输出,并且 console.log 没有显示带 $ 的键的符号。

  3. 假设第 2 步实际上由于 key 中的 $ 而失败,但事实并非如此,我有另一个 JSON,它是调查的响应并且不包含任何 $,但它也失败并出现相同的错误(MongoError:键 $ 不能以“$”开头)。

    db.collection('submissions').insert(jsonObject, function(err, result) {
      if(err) console.log('error is : ' + err);
      console.log('insertion result : ' + JSON.stringify(result));
    });
    

下面是XML表单提交

   <?xml version='1.0' ?>
   <ppe id="ppe_checklist_new">
    <starting_repeat>
        <location>dark_room</location>
        <ppe_dark>safety_glasses</ppe_dark>
        <xyz_group>
            <condition>condition_missing</condition>
            <test_condition>b</test_condition>
        </xyz_group>
    </starting_repeat>
    <starting_repeat>
        <location>nitrogen_store</location>
        <ppe_nitrogen>leather_gloves_s</ppe_nitrogen>
        <xyz_group>
            <condition>condition_replacing</condition>
            <test_condition />
        </xyz_group>
    </starting_repeat>
    <starting_repeat>
        <location>nitrogen_store</location>
        <ppe_nitrogen>blue_gloves_m</ppe_nitrogen>
        <xyz_group>
            <condition />
            <test_condition>b</test_condition>
        </xyz_group>
    </starting_repeat>
    <starting_repeat>
        <location>cold_room_first</location>
        <ppe_cold>hearing_muff_1</ppe_cold>
        <xyz_group>
            <condition>condition_ok</condition>
            <test_condition>f</test_condition>
        </xyz_group>
    </starting_repeat>
    <sample_group>
        <date>2015-08-24</date>
        <random_number>55</random_number>
    </sample_group>
    <another_group>
        <another_repeat>
            <sample_text>Sample text 1</sample_text>
            <image />
        </another_repeat>
        <another_repeat>
            <sample_text>Sample text 2</sample_text>
            <image />
        </another_repeat>
    </another_group>
    <form_done>OK</form_done>
    <survey_start>2015-08-24T16:55:23.185+01</survey_start>
    <survey_end>2015-08-24T16:57:24.460+01</survey_end>
    <survey_day>2015-08-24</survey_day>
    <survey_device>353490061313389</survey_device>
    <meta>
        <instanceID>uuid:2aba0eff-5350-47e3-9e9c-9606d2c9e7d6</instanceID>
    </meta>
</ppe>

我将以上内容提供给具有以下配置的 xml2js 模块:

function parseXMLToJS(filename, path, callback) {
  var parser = new xml2js.Parser({explicitArray:false});
  var fileURL = path + filename;

  var data = fs.readFile(fileURL, function(err, data) {
    if(err) {
      logger.error('Error reading submission file. Error %', err);
    } else {
      parser.parseString(data, function (err, result) {
        if(err) {
          logger.error('Error parsing XML to JS. Error : %',  err);
          callback({parsed:false, result:result});
        } else {
          callback({parsed:true, result:result});
        }
      });
    }
  });
}

并且模块生成一个 JSON 对象,如下所示:

{
    "ppe": {
        "starting_repeat": [
            {
                "location": "dark_room",
                "ppe_dark": "safety_glasses",
                "xyz_group": {
                    "condition": "condition_missing",
                    "test_condition": "b"
                }
            },
            {
                "location": "nitrogen_store",
                "ppe_nitrogen": "leather_gloves_s",
                "xyz_group": {
                    "condition": "condition_replacing",
                    "test_condition": ""
                }
            },
            {
                "location": "nitrogen_store",
                "ppe_nitrogen": "blue_gloves_m",
                "xyz_group": {
                    "condition": "",
                    "test_condition": "b"
                }
            },
            {
                "location": "cold_room_first",
                "ppe_cold": "hearing_muff_1",
                "xyz_group": {
                    "condition": "condition_ok",
                    "test_condition": "f"
                }
            }
        ],
        "sample_group": {
            "date": "2015-08-24",
            "random_number": "55"
        },
        "another_group": {
            "another_repeat": [
                {
                    "sample_text": "Sample text 1",
                    "image": ""
                },
                {
                    "sample_text": "Sample text 2",
                    "image": ""
                }
            ]
        },
        "form_done": "OK",
        "survey_start": "2015-08-24T16:55:23.185+01",
        "survey_end": "2015-08-24T16:57:24.460+01",
        "survey_day": "2015-08-24",
        "survey_device": "353490061313389",
        "id": "ppe_checklist_new",
        "uuid": "2aba0eff-5350-47e3-9e9c-9606d2c9e7d6"
    }
}

我尝试检查我插入到 MongoDB 的数据是否是对象,结果是。

typeof(result.result)
  1. 尝试通过 Mongo Shell 插入从 xml2js 生成的 JSON 对象,它成功了。
  2. 尝试在我的 javascript 代码中创建一个 JS 对象,其内容与 xml2js 生成的 JSON 相同,并通过 mongodb native 驱动程序将其插入到 MongoDB 中(尽管我比较了两个 JSON,它们完全相同)。

总之,我可以说 mongodb 原生驱动不喜欢 xml2js 模块生成的 JSON 对象,我不知道为什么?我等不及要知道了。我尝试了以下解决方法

  1. 使用 xml2js 转换 XML 2 JSON
  2. 将 xml2js 返回的 JSON 对象字符串化 (x = JSON.stringify(obj);)
  3. 解析字符串化的 JSON 对象 (parsedX = JSON.parse(x);)
  4. 通过 mongodb native 驱动器将解析后的值插入到 MongoDB 中,并且成功了。

无论是什么问题,上面的错误消息都具有误导性,或者可能不适合导致它的问题。我找不到获得更详细错误的方法(也许 mongodb 提供了更多解释的方法,很想知道)。

感谢您的时间和耐心。

最佳答案

traverse 函数的下一行只是将 $ 字段设置为 undefined 的值,而没有实际删除它。

o[i].$ = undefined;

更改该行以使用 delete 来删除它:

delete o[i].$;

使用 JSON.stringifyJSON.parse 的解决方法有效,因为 undefined 值无法用 JSON 表示,因此 JSON.stringify 调用删除具有该值的字段。

关于json - 蒙哥错误: key $ must not start with '$' when store JSON object generated by xml2js module,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32203337/

相关文章:

node.js - 如何为 Electron 应用程序安装程序设置自定义路径

java - 无法检索 JSON 值

javascript - JSON 结果从 address_components 获取国家

javascript - 如何为JSON对象中的每个叶节点生成JSON路径?

xml - Groovy Xml Holder 返回 'null' 作为现有属性的值

Node.js请求网页

java - 实现PATCH操作Play - Java

c# - 如何验证 XML 文档?

c# - 如何将要在某些 XElement 上执行的操作作为参数传递?

node.js - Node/ express : concurrency issues when using session to store state