6
votes

Stax - Obtenez un nœud XML en tant que chaîne

XML ressemble à:

String statementXml = staxXmlReader.getNodeByName("statement");

//load statementXml into database


1 commentaires

Quelle est votre question exactement?


6 Réponses :


1
votes

J'ai googling et cela semble douloureusement difficile.

Compte tenu de mon XML, je pense qu'il pourrait être plus simple de: P>

StringBuilder buffer = new StringBuilder();
for each line in file {
   buffer.append(line)
   if(line.equals(STMT_END_TAG)){
      parse(buffer.toString())
      buffer.delete(0,buffer.length)
   }
 }

 private void parse(String statement){
    //saxParser.parse( new InputSource( new StringReader( xmlText ) );
    // do stuff
    // save string
 }


0 commentaires

0
votes

Pourquoi ne pas simplement utiliser xpath pour cela?

Vous pouvez avoir un xpath assez simple pour obtenir tous les nœuds de "déclaration". P>

Comme: P>

String text = "your xml here";
Document document = DocumentHelper.parseText(text);

public void bar(Document document) {
   List list = document.selectNodes( "//statement" );
   // loop through node data
}


3 commentaires

Il y a aussi des bibliothèques Standard XPath dans la JDK / JRE: Stackoverflow.com/Questtions/3939636/...


L'affiche a explicitement mentionné Stax, donc je ne pense pas que les pointeurs à dom4j ou à une autre bibliothèque l'ait aidé beaucoup ...


Étant donné que l'OP n'a jamais posé une question, la suggestion d'utiliser XPath est aussi bonne que n'importe quoi. Peut-être mieux.



4
votes

Stax est une API d'accès de bas niveau, et il n'a pas de recherche ni de méthodes qui accèdent le contenu récursivement. Mais qu'est-ce que tu essayes réellement de faire? Et pourquoi considérons-tu Stax?

Au-delà de l'utilisation d'un modèle d'arbre (DOM, XOM, JDOM, DOM4J), qui fonctionnerait bien avec XPath, le meilleur choix lors de la gestion des données est généralement une bibliothèque de liaison de données comme JAXB. Avec vous, vous pouvez passer des lecteurs Stax ou Sax et de lui demander de lier les données XML dans les haricots Java et au lieu de jouer avec des objets Java de processus XML. Cela est souvent plus pratique et c'est généralement une performance. Seuls truc avec des fichiers plus gros est que vous ne souhaitez pas lier le tout à la fois, mais plutôt lier chaque sous-arbre (dans votre cas, une «déclaration» à la fois). Ceci est le plus facile fait par itération de Stax XmlstreamReader, puis en utilisant Jaxb pour lier.


0 commentaires

6
votes

Vous pouvez utiliser Stax pour cela. Il vous suffit de faire avancer la xmlstreamreader à l'élément de départ de la déclaration. Vérifiez l'attribut de compte pour obtenir le nom du fichier. Utilisez ensuite les API de Javax.xml.Transform pour transformer le StaxSource en un fichier d'enveloppe StreamResult. Cela avancera la xmlstreamreader puis répétera ce processus.

import java.io.File;
import java.io.FileReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;

public class Demo {

    public static void main(String[] args) throws Exception  {
        XMLInputFactory xif = XMLInputFactory.newInstance();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
        xsr.nextTag(); // Advance to statements element

        while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            File file = new File("out" + xsr.getAttributeValue(null, "account") + ".xml");
            t.transform(new StAXSource(xsr), new StreamResult(file));
        }
    }

}


3 commentaires

Utiliser tandis que (xsr.nexttag ...) échouera. La documentation Stax pour xsr.nexttag () indique qu'une exception sera lancée si xsr.hasnext () est une erreur fausse et la prochaine étape est appelée. De plus, lors de l'utilisation de xsr.NextTag (), si autre que des caractères d'espace blanc, commentaire, traitement_instruction, start_element, end_élément sont rencontrés, une exception est lancée.


Lorsque j'utilise le code ci-dessus, je reçois l'exception d'erreur suivante dans le thread "Main" net.sf.saxon.trans.xpathException: org.w3c.dom.domException: hierarchy_request_err: une tentative a été faite pour insérer un nœud où il se trouve pas permis. Une idée?


Appelant conceptuellement xsr.nexttag () est faux car xmlstreamreader peut-être déjà à partir de la balise droite si "INPUT.XML" ne contient pas d'en-têtes. Essayer tous les cas possibles Je reçois toujours l'erreur: Java.lang.illegalStateException: tentative de sortie de la balise finale sans étiquette de démarrage de correspondance. @ T0R0X Solution est le seul valable pour moi



10
votes

J'ai eu une tâche similaire et, bien que la question initiale soit antérieure à une année, je n'ai pas pu trouver une réponse satisfaisante. La réponse la plus intéressante jusqu'à présent était la réponse de Blaise Dumdan, mais je ne pouvais pas le faire courir sur le XML que je m'attends (peut-être que certains paramètres pour l'analyseur sous-jacent pouvaient changer cela?). Ici, le XML, très simplementFied: xxx pré>

ma solution: p> xxx pré>

EXEMPLE D'UTILISATION: P>

'
    <description>
        ...
        <p>Lorem ipsum...</p>
        Devils inside...
        ...
    </description>
    '


2 commentaires

Y a-t-il un moyen d'imprimer la chaîne sans l'espace de noms?


Je ne suis pas sûr de comprendre votre question, quel espace de noms? Pouvez-vous donner un exemple?



0
votes

J'ai eu le problème similaire et j'ai trouvé la solution. J'ai utilisé la solution proposée par @ t0r0x, mais cela ne fonctionne pas bien dans la mise en œuvre actuelle en Java 11, la méthode xmlevent.writeeeCodeDunicode crée la représentation de chaîne non valide de l'élément de démarrage (dans le starteleeventevent classe) Dans le fragment XML des résultats, je devais donc le modifier, mais il semble que je puisse bien fonctionner, ce que je pouvais vérifier immédiatement par l'analyse du fragment de Dom et Jaxbmarshaller à des conteneurs de données spécifiques.

Dans mon cas, j'ai eu la structure énorme xxx

dans le fichier de plusieurs centaines de mégaoctets (beaucoup de structures de synchronisation répétitives), l'utilisation de DOM conduirait à un Grande consommation de mémoire et évaluation lente. Par conséquent, j'ai utilisé le Stax pour diviser l'énorme XML sur des pièces XML plus petites, que j'ai analysées avec DOM et utilisé les jaxbelements générés à partir de la définition XSD de l'élément Syncorder (cette infrastructure que j'avais du site Web, qui utilise la même structure, mais ce n'est pas important).

Dans ce code, on peut voir que le fragment XML a créé et pourrait être utilisé, je l'ai utilisé directement dans un autre traitement ... < / p> xxx


0 commentaires