2012-02-28 12 views
7

Ho bisogno di analizzare una stringa XML con MATLAB (attenzione: senza I/O di file, quindi non voglio scrivere la stringa in un file e quindi leggerle). Sto ricevendo le stringhe da una connessione HTTP e l'analisi dovrebbe essere molto veloce. Sono principalmente preoccupato di leggere i valori di alcuni tag nell'intera stringaAnalisi di stringhe XML in MATLAB

La rete è piena di minacce di morte sull'analisi di XML con espressioni regolari, quindi non volevo ancora entrare in quella. So che MATLAB ha una perfetta integrazione con Java ma non sono molto esperto di Java. C'è un modo rapido per ottenere determinati valori da XML molto molto rapidamente?

Ad esempio, voglio ottenere le informazioni "volume" da questa stringa in basso e scriverle su una variabile.

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 


<root> 
    <volume>256</volume> 
    <length>0</length> 
    <time>0</time> 
    <state>stop</state> 
    .... 
+0

Stai usando Windows? Se è così, allora posso offrirti una soluzione .NET. –

risposta

1

C'è un intero class of functions per trattare con XML, tra cui xmlread e xmlwrite. Quelli dovrebbero essere piuttosto utili per il tuo problema.

+2

Ma ha detto esplicitamente che non vuole trattare con i file –

7

Per quel che vale, sotto è il codice eseguibile Java Matlab per svolgere il compito richiesto, senza scrivere ad un file intermedio:

%An XML formatted string 
strXml = [... 
    '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>' char(10)... 
    '<root>' char(10) ... 
    ' <volume>256</volume>' char(10) ... 
    ' <length>0</length>' char(10) ... 
    ' <time>0</time>' char(10) ... 
    ' <state>stop</state>' char(10) ... 
    '</root>' ]; 

%"simple" java code to create a document from said string 
xmlDocument = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder.parse(java.io.StringBufferInputStream(strXml)); 

%"intuitive" methods to explore the xmlDocument 
nodeList = xmlDocument.getElementsByTagName('volume'); 
numberOfNodes = nodeList.getLength(); 

firstNode = nodeList.item(0); 
firstNodeContent = firstNode.getTextContent; 

disp(firstNodeContent); %Returns '256' 

In alternativa, se l'applicazione lo consente, in considerazione passando l'URL direttamente nel parser XML. Il codice java non testato è sotto, ma probabilmente apre anche la funzione integrata di Matlab xslt.

xmlDocument = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder.parse('URL_AS_A_STRING_HERE'); 

Documentazione here. Inizia dal pacchetto "javax.xml.parsers".

1

Non ho alcuna familiarità con le API di Matlab, ma vorrei sottolineare che l'uso del metodo DOM descritto da Pursuit richiederà più tempo/memoria se si desidera solo valori specifici dallo stream XML di cui si sta tornando indietro la connessione HTTP.

Mentre STAX offre l'approccio di parsing più veloce in Java, l'utilizzo dell'API può essere poco maneggevole, soprattutto se non si ha dimestichezza con Java. È possibile utilizzare SJXP che è un'astrazione estremamente sottile ontop dell'analisi STAX in Java (dichiarazione di non responsabilità: I am the author) che consente di definire i percorsi degli elementi che si desidera, quindi si dà al parser un flusso (il flusso HTTP in questo caso) e tira fuori tutti i valori per te.

Per fare un esempio, diciamo che si voleva i valori/root/Stato e/root/volume fuori dal XML esempi che hai postato, l'attuale Java sarebbe simile a questa:

// Create /root/state rule 
IRule stateRule = new DefaultRule(Type.CHARACTER, "/root/state") { 
    @Override 
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) { 
     System.out.println("State is: " + text); 
    } 
} 

// Create /root/volume rule 
IRule volRule = new DefaultRule(Type.CHARACTER, "/state/volume") { 
    @Override 
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) { 
     System.out.println("Volume is: " + text); 
    } 
} 

// Create the parser with the given rules 
XMLParser parser = new XMLParser(stateRule, volRule); 

Si può fare tutti che l'inizializzazione all'avvio del programma poi ad un certo punto più tardi, quando si elaborano il flusso dalla vostra connessione HTTP, si potrebbe fare qualcosa di simile:

parser.parser(httpConnection.getOutputStream()); 

o simili; quindi tutto il codice del gestore definito nelle regole verrà richiamato mentre il parser esegue il flusso di caratteri dalla connessione HTTP.

Come ho già detto non ho familiarità con Matlab e non conosco il modo corretto di "Matlab-i-fy" questo codice, ma dal primo esempio si può più o meno usare le API Java direttamente nel qual caso questa soluzione sarà più veloce e utilizzerà meno memoria per l'analisi se ciò è importante rispetto all'approccio DOM.