title: Node.js NET concatenate chunked XML data
body: <p>I am receiving XML/SOAP through a NET socket in Node. The larger SOAP responses are chunked so i need to concatenate the SOAP envelope before i pass it to the XML parser.</p>
  
  <p>Here is the attempt so far</p>
  
  <pre><code>//client.net.setEncoding('utf8');
  var data = '';
  client.net.on('data', function(response) {
      var read = response.toString();
      console.log("READING == "+read);
      if (read.substr(read.length-15) === "&lt;/env:Envelope&gt;") {
          if(data.length &gt; 0) {
              /* soap envelope is finally complete, pass to xml parser */
              parser.parseString(data += response);
              data = '';
          }
          /* soap envelope is complete, pass to xml parser */
          parser.parseString(response);
      } else {
          /* not soap response */
          if (read.substr(0, 4) === "HTTP") return;
          /* add chunck to data */
          data += response;
      }
  });
  </code></pre>
  
  <p>The incoming data looks like (these are small responses)</p>
  
  <pre><code>READING == HTTP/1.1 200 OK
  Content-Type:application/soap+xml; charset="utf-8"
  Content-Length:644
  
  
  READING == &lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"&gt;&lt;env:Header&gt;&lt;n:Response x
  mlns:n="http://www.example.com/" env:role="http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver" env:mustUnderst
  and="true"&gt;SetTrackingFrequency&lt;/n:Response&gt;&lt;/env:Header&gt;&lt;env:Body&gt;&lt;n:ResponseSetTrackingFrequency xmlns:n="http://www.example.com/ipr
  s/gps/soap"&gt;&lt;n:Status&gt;none&lt;/n:Status&gt;&lt;n:ApplicationID&gt;18&lt;/n:ApplicationID&gt;&lt;n:RequestID&gt;0&lt;/n:RequestID&gt;&lt;n:FrequencySecs&gt;0&lt;/n:FrequencySecs&gt;&lt;n
  :ExpirationSecs&gt;0&lt;/n:ExpirationSecs&gt;&lt;/n:ResponseSetTrackingFrequency&gt;&lt;/env:Body&gt;&lt;/env:Envelope&gt;
  </code></pre>
  
  <p>When the envelope is not complete i am merging the chunks.</p>
  
  <p>This appears to nearly work, except the parser starts to throw error.</p>
  
  <pre><code>error: uncaughtException: Text data outside of root node.
  </code></pre>
  
  <p><strong>Edit - further info</strong></p>
  
  <p>This code gives the error, but passing same response?</p>
  
  <pre><code>client.net.on('data', function(response) {
      var read = response.toString();
      if (read.substr(read.length-15) === "&lt;/env:Envelope&gt;") {
          parser.parseString(response);
          return;
      }
  }
  </code></pre>
  
  <p>This code gives no error</p>
  
  <pre><code>client.net.on('data', function(response) {
          parser.parseString(response);
          return;
  }
  </code></pre>
  
  <p><strong>Full error:</strong></p>
  
  <pre><code>2015-11-13T19:34:50.355Z - error: uncaughtException: Text data outside of root node.
  Line: 0
  Column: 1228
  Char: H date=Fri Nov 13 2015 19:34:50 GMT+0000 (GMT Standard Time), pid=25712, uid=null, gid=null, cwd=C:\Users\v_lowe\Dropbox\nodejs\v4 -of
  , execPath=C:\Program Files\nodejs\node.exe, version=v4.1.1, argv=[C:\Program Files\nodejs\node.exe, C:\Users\v_lowe\Dropbox\nodejs\v4 -of\i
  ndex.js], rss=44589056, heapTotal=34005760, heapUsed=21471184, loadavg=[0, 0, 0], uptime=954829.8959002, trace=[column=10, file=-of\node_mod
  ules\xml2js\node_modules\sax\lib\sax.js, function=error (C:\Users\v_lowe\Dropbox\nodejs\v4, line=666, method=null, native=false, column=7, f
  ile=-of\node_modules\xml2js\node_modules\sax\lib\sax.js, function=strictFail (C:\Users\v_lowe\Dropbox\nodejs\v4, line=692, method=null, nati
  ve=false, column=15, file=-of\node_modules\xml2js\node_modules\sax\lib\sax.js, function=Object.write (C:\Users\v_lowe\Dropbox\nodejs\v4, lin
  e=1035, method=write (C:\Users\v_lowe\Dropbox\nodejs\v4, native=false, column=31, file=-of\node_modules\xml2js\lib\xml2js.js, function=Parse
  r.exports.Parser.Parser.parseString (C:\Users\v_lowe\Dropbox\nodejs\v4, line=497, method=exports.Parser.Parser.parseString (C:\Users\v_lowe\
  Dropbox\nodejs\v4, native=false, column=59, file=-of\node_modules\xml2js\lib\xml2js.js, function=Parser.parseString (C:\Users\v_lowe\Dropbox
  \nodejs\v4, line=7, method=parseString (C:\Users\v_lowe\Dropbox\nodejs\v4, native=false, column=12, file=-of\lib\gps_parse.js, function=Sock
  et.&lt;anonymous&gt; (C:\Users\v_lowe\Dropbox\nodejs\v4, line=41, method=&lt;anonymous&gt; (C:\Users\v_lowe\Dropbox\nodejs\v4, native=false, column=13,
  file=events.js, function=emitOne, line=77, method=null, native=false, column=7, file=events.js, function=Socket.emit, line=169, method=emit,
   native=false, column=16, file=_stream_readable.js, function=readableAddChunk, line=146, method=null, native=false, column=10, file=_stream_
  readable.js, function=Socket.Readable.push, line=110, method=Readable.push, native=false], stack=[Error: Text data outside of root node., Li
  ne: 0, Column: 1228, Char: H,     at error (C:\Users\v_lowe\Dropbox\nodejs\v4 -of\node_modules\xml2js\node_modules\sax\lib\sax.js:666:10),
     at strictFail (C:\Users\v_lowe\Dropbox\nodejs\v4 -of\node_modules\xml2js\node_modules\sax\lib\sax.js:692:7),     at Object.write (C:\User
  s\v_lowe\Dropbox\nodejs\v4 -of\node_modules\xml2js\node_modules\sax\lib\sax.js:1035:15),     at Parser.exports.Parser.Parser.parseString (C:
  \Users\v_lowe\Dropbox\nodejs\v4 -of\node_modules\xml2js\lib\xml2js.js:497:31),     at Parser.parseString (C:\Users\v_lowe\Dropbox\nodejs\v4
  -of\node_modules\xml2js\lib\xml2js.js:7:59),     at Socket.&lt;anonymous&gt; (C:\Users\v_lowe\Dropbox\nodejs\v4 -of\lib\gps_parse.js:41:12),     a
  t emitOne (events.js:77:13),     at Socket.emit (events.js:169:7),     at readableAddChunk (_stream_readable.js:146:16),     at Socket.Reada
  ble.push (_stream_readable.js:110:10)]
  </code></pre>