2010-07-21 4 views
6

Je suis dans une position où j'utilise Java pour me connecter à un port TCP et diffuser des documents XML les uns après les autres, chacun délimité par le <?xml de l'étiquette de document. Un exemple qui démontre le format:Utilisation de SAX (Java) pour analyser plusieurs messages XML à partir d'un seul flux TCP

<?xml version="1.0"?> 
<person> 
    <name>Fred Bloggs</name> 
</person> 
<?xml version="1.0"?> 
<person> 
    <name>Peter Jones</name> 
</person> 

J'utilise le org.xml.sax.* api. L'analyse syntaxique SAX fonctionne parfaitement pour le premier document mais lance une exception en ce qui concerne tout le début du second document:

Exception in thread "main" org.xml.sax.SAXParseException: The processing instruction 
target matching "[xX][mM][lL]" is not allowed. 

La classe squelette suivant montre la configuration que je utilise:

import org.xml.sax.InputSource; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 
import org.xml.sax.helpers.XMLReaderFactory; 

import java.io.FileReader; 

public class XMLTest extends DefaultHandler { 

    public XMLTest() { 
    super(); 
    } 

    public static void main(String[] args) throws Exception { 
    XMLReader xr = XMLReaderFactory.createXMLReader(); 

    XMLTest handler = new XMLTest(); 
    xr.setContentHandler(handler); 
    xr.setErrorHandler(handler); 

    xr.parse(new InputSource(new Socket("127.0.0.1", 4555).getInputStream())); 
    } 
} 

Je n'ai aucun contrôle sur le format du XML (c'est un flux de données financières), mais je dois pouvoir l'analyser efficacement et analyser tous les documents. J'ai passé l'après-midi/soirée à essayer différentes choses mais aucune n'a donné de résultats. Toute aide serait grandement appréciée.

+0

Vous devez appeler analyse pour chaque document séparé, ce qui signifie que vous devez filtrer et diviser le flux d'entrée sur les caractères '

+0

Je devais faire quelque chose comme ça et juste répondu (à moi-même) [ici] (http://stackoverflow.com/questions/6711766/multiple-xml-files-in-one-stream/) enveloppant tout dans son propre lecteur pour une utilisation plus simple –

Répondre

6

Vous souhaitez diviser le flux sur chaque <?xml version="1.0"?> et les analyser tous séparément. Le BufferedReader peut être utile dans ce cas. Exemple de lancement:

reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); 
StringBuilder builder = null; 
for (String line; (line = reader.readLine()) != null;) { 
    if (line.startsWith("<?xml")) { 
     if (builder != null) { 
      xr.parse(new InputSource(builder.toString())); 
     } 
     builder = new StringBuilder(); 
    } 
    builder.append(line); 
} 
+0

En faisant cela quand 'input' est' InputStream input = new Socket ("127.0.0.1", 4500) .getInputStream(); 'Je reçois l'exception suivante: Exception dans le fil" main "java.io .FileNotFoundException:/Users/admin/IdeaProjects/XMLTest/<(aucun fichier ou répertoire de ce type) at java.io.FileInputStream.open (méthode native) at java.io.FileInputStream. (FileInputStream.java:106) à java.io.FileInputStream. (FileInputStream.java:66) Il semble que xr.parse() n'aime pas les chaînes, même lorsqu'elles sont enveloppées comme InputSource. – jkt

+0

Vous considérez-vous capable d'interpréter des stacktraces? Je ne vois pas comment 'FileNotFoundException' est lié à tout cela. Je dirais que votre problème se situe ailleurs, peut-être dans l'étape au-delà de l'analyse syntaxique. Le message d'exception dans le nom de fichier '/ Users/admin/IdeaProjects/XMLTest/<' ne semble en effet pas valide btw. Relisez la pile, retournez le bon emplacement dans le code qui a provoqué cela en fonction des numéros de ligne dans la trace, clouez la cause et corrigez-la. Si vous êtes bloqué et que ce problème n'est en effet pas lié à cette question, posez une nouvelle question (par exemple "Comment sauvegarder un fichier XML?"). – BalusC

+0

Hé, Je peux lire des stacktraces - j'ai seulement collé les premières lignes. Le pointeur stacktrace vers mon code est 'atTest.Test.Main (XMLTest.java:42)' et la ligne 42 est: 'xr.parse (nouvelle InputSource (builder.toString()));' (qui est de votre exemple ci-dessus) . J'apprécie votre aide avec ceci. – jkt

Questions connexes