草庐IT

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

coder 2023-10-28 原文

各位

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/

有关json - 蒙哥错误: key $ must not start with '$' when store JSON object generated by xml2js module的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  10. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

随机推荐