2015-03-21 15 views
5

Sto cercando di analizzare XML con una chiamata HTTP nel back-end in cui il corpo è in XML. Il problema è che non possiamo usare Jquery o DOMParser nel back-end per analizzare. Abbiamo provato a analizzarlo prima nel front-end, quindi inviarlo al metodo meteor (nel back-end) come variabile, ma era troppo grande (supera lo stack massimo). Abbiamo anche provato ad aggiungere un modulo nodo per farlo ma non ha funzionato correttamente.Come analizzare XML nel backend Meteor?

Come possiamo ottenere un oggetto XML analizzato nel back-end di Meteor?

risposta

1

Abbiamo provato ad aggiungere un modulo nodo per farlo ma non ha funzionato correttamente.

È possibile che si sia inciampato su dipendenze non compatibili.

Provare node-xml2js, che richiede solo sax.js, che richiede solo JavaScript.

2

aggiungere il pacchetto xml2js, creare un metodo Meteor e mettere qualcosa di simile all'interno,

xml2js.parseString(xml, function (err, result) { 
    console.dir(result); 
}); 

Poi lo chiamano dal client. Dovresti vedere il tuo xml analizzato in json nella tua console meteor.

10

Per prima cosa è necessario installare un paio di pacchetti.

  1. HTTP, in modo da poter "GET" l'XML esterno
  2. xml2js, in modo da poter analizzare il codice XML, una volta si presenta

Installare e riavviare il server in questo modo:

meteor add http peerlibrary:xml2js && meteor 

In secondo luogo, creare una funzione sul lato server. Non deve essere un metodo Meteor, ma per questo esempio, lo inserirò in uno così potremo facilmente attivarlo. Utilizzare HTTP.call() or HTTP.get() per effettuare la richiesta. Quindi l'URL; Userò un file XML di esempio. Quindi i parametri after-URL; nel mio caso non ce ne sono. Quindi la funzione di callback.

Meteor.methods({ 
    'xmlDemo':function(){ 
     HTTP.call('GET', 
      'http://www.xmlfiles.com/examples/plant_catalog.xml', 
      {}, 
      function(callError,callResponse){ 
       console.log('xml',callResponse); 
      } 
     ); 
    } 
}); 

Se siete nuovi a Meteor, prendere nota speciale del parametro "errore" prima nella funzione di callback.

In terzo luogo, provare il metodo. Questo è come un gioco di telefono.

  1. Il client chiama il server meteorologico. Meteor.call('xmlDemo');
  2. Il server meteorologico chiama l'URL esterno.

Se tutto va bene, il metodo legge il contenuto del file e visualizza l'output sulla console del server. (Vale a dire Guardate il terminale in cui si esegue "Meteor")

{ statusCode: 200, 
content: '<?xml version="1.0" encoding="ISO8859-1" ?>\r\n<CATALOG>\r\n 
(et cetera...) 
(et cetera...) 
(et cetera...)', 
headers: 
{ 'content-type': 'text/xml', 
    'last-modified': 'Tue, 24 Apr 2012 21:06:45 GMT', 
    'accept-ranges': 'bytes', 
    etag: '"80a095275e22cd1:0"', 
    server: 'Microsoft-IIS/7.5', 
    'x-powered-by': 'ASP.NET', 
    date: 'Mon, 30 Nov 2015 19:17:26 GMT', 
    'content-length': '8167' }, 
data: null } 

La cosa più importante visto qui è che la risposta da HTTP.call è un oggetto. Il campo "contenuto" contiene i dati effettivi. (Questo è il posto dove sono stato inciampato personalmente.)

In quarto luogo, provare a passare la stringa XML in xml2js.

Meteor.methods({ 
    'xmlDemo':function(){ 
     HTTP.call('GET', 
      'http://www.xmlfiles.com/examples/plant_catalog.xml', 
      {}, 
      function(callError,callResponse){ 
       //console.log('xml',callResponse); 
       xml2js.parseString(callResponse.content, function (jsError, jsResult) { 
        console.error('errors',jsError); 
        console.log('xml to js',jsResult); 
       }); 
      } 
     ); 
    } 
}); 

Ancora, con un po 'di fortuna, vedrai le piante come oggetti stampati nel tuo terminale. Tutto quello che devi fare ora è prendere quell'array di oggetti, passarci sopra e archiviarli in una collezione. Underscore rende facile (è costruito a Meteor)

_.each(jsResult.CATALOG.PLANT,function(plant){ 
    Plants.insert(plant); 
} 

Ultima si dovrebbe aggiungere qualche paio di fail-cassette di sicurezza per segnalare gli errori. Anche xml2js out of the box non funzionerà necessariamente bene come funzionano le raccolte. È necessario set a few options.

  • explicitArray: false (.. Per impostazione predefinita, un tag come <this>example</this> si trasformerebbe in {this:["example"]} In Mongo, che è considerato un documento incorporato, e si avranno problemi)
  • emptytag: undefined (per impostazione predefinita, un tag vuoto come <this/> sarebbe trasformato in {this:''}. Personalmente, sento che è più facile lasciare che le cose vuoti non esistono e controllare se esistono o meno, piuttosto che controllare se esistono e in realtà avere un contenuto)

Dopo la pulizia un po ' codice mio, ecco l'ultimo esempio

su un /lib/file.js ...

Plants = new Mongo.Collection('plants'); 

su un /server/file.js ...

Meteor.methods({ 
    'xmlDemo':function(){ 
     HTTP.get('http://www.xmlfiles.com/examples/plant_catalog.xml',{}, 
      function(xmlError,xmlResponse){ 
       if(xmlError){ 
        console.error('xmlError',xmlError); 
       }else{ 
        xml2js.parseString(xmlResponse.content, {explicitArray:false, emptyTag:undefined}, function (jsError, jsResult) { 
        if(jsError){ 
         console.error('xml2js error',jsError); 
        }else{ 
         _.each(jsResult.CATALOG.PLANT,function(plant){ 
          Plants.insert(plant); 
         } 
        } 
       }); 
      } 
     ); 
    } 
});