2010-07-28 8 views
4

Est-il possible d'ignorer des nœuds lors de l'analyse et comment cela a-t-il un rapport avec skippedEntity?Ignorer des nœuds avec sax

Considérez ceci XML:

<?xml version="1.0"?> 

<nutrition> 

<daily-values> 
    <total-fat units="g">65</total-fat> 
    <saturated-fat units="g">20</saturated-fat> 
    <cholesterol units="mg">300</cholesterol> 
    <sodium units="mg">2400</sodium> 
    <carb units="g">300</carb> 
    <fiber units="g">25</fiber> 
    <protein units="g">50</protein> 
</daily-values> 

</nutrition> 

Je veux sauter élément « de sodium »

Répondre

7

Vous pouvez faire quelque chose comme ce qui suit:

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 
import org.xml.sax.XMLReader; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 
     xr.setContentHandler(new MyContentHandler(xr)); 
     xr.parse("input.xml"); 
    } 
} 

MyContentHandler

Cette classe est responsable du traitement de votre document XML. Lorsque vous frappez un nœud que vous voulez ignorer, vous pouvez permuter dans IgnoringContentHandler qui va avaler tous les événements pour ce nœud.

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 

public class MyContentHandler extends DefaultHandler { 

    private XMLReader xmlReader; 

    public MyContentHandler(XMLReader xmlReader) { 
     this.xmlReader = xmlReader; 
    } 

    public void startElement(String uri, String localName, String qName, 
      Attributes atts) throws SAXException { 
     if ("sodium".equals(qName)) { 
      xmlReader.setContentHandler(new IgnoringContentHandler(xmlReader, 
        this)); 
     } else { 
      System.out.println("START " + qName); 
     } 
    } 

    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
     System.out.println("END " + qName); 
    } 

    public void characters(char[] ch, int start, int length) 
      throws SAXException { 
     System.out.println(new String(ch, start, length)); 
    } 

} 

IgnoringContentHandler

Lorsque le IgnoringContentHandler est fait des événements avaler passe le contrôle à votre ContentHandler principale.

import org.xml.sax.Attributes; 
import org.xml.sax.ContentHandler; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 

public class IgnoringContentHandler extends DefaultHandler { 

    private int depth = 1; 
    private XMLReader xmlReader; 
    private ContentHandler contentHandler; 

    public IgnoringContentHandler(XMLReader xmlReader, ContentHandler contentHandler) { 
     this.contentHandler = contentHandler; 
     this.xmlReader = xmlReader; 
    } 

    public void startElement(String uri, String localName, String qName, 
      Attributes atts) throws SAXException { 
     depth++; 
    } 

    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
     depth--; 
     if(0 == depth) { 
      xmlReader.setContentHandler(contentHandler); 
     } 
    } 

} 
+0

pas d'infraction, mais le code semble terriblement complexe pour moi .. –

+0

@ vtd-xml-author - J'ai changé le code pour étendre DefaultHandler plutôt que d'implémenter ContentHandler directement, cela devrait rendre le code plus facile à comprendre. Le chaînage de gestionnaires de contenu est un mécanisme très puissant dans l'analyse syntaxique SAX standard. –

+0

erreur, ce code ne fonctionne pas. – Wayne

3

S'il vous plaît modifier votre message pour inclure un exemple XML et une description de ce que vous par « ignorer les noeuds » .

Étant donné que votre analyseur contrôle chaque événement, vous pouvez choisir de ne rien faire en fonction des critères que vous désirez. Si vous voulez ignorer une sous-arborescence entière, vous devez définir un indicateur global lorsque vous rencontrez l'élément de début du sous-arbre et effacer le drapeau à l'élément de fin; Utilisez ensuite l'indicateur pour contrôler le traitement des noeuds contenus.

+0

J'ai ajouté xml, je veux sauter l'élément "sodium" – London

+0

OK, que voulez-vous dire par "sauter"? Dans un analyseur SAX, vous avez le contrôle ... vous obtenez des événements d'analyse et vous pouvez faire ce que vous voulez. Vous obtiendrez un événement start-element pour chaque tag, et lorsque le nom du tag est "sodium", vous pouvez écrire une logique pour revenir simplement, en ignorant les données. Modifiez votre message et montrez ce que vous avez essayé jusqu'à présent en Java. –

1

Malheureusement, je n'ai pas le privilège de commenter d'autres réponses. Je voulais juste corriger l'affirmation incorrecte de Wayne selon laquelle la réponse de Blaise «ne fonctionne pas». J'ai essayé ce code et il produit en effet toutes les valeurs des données d'exemple excepté celle pour le sodium - qui je pense est exactement ce que le PO recherchait.