Explication détaillée de l'analyse XML SAX

PHPz
Libérer: 2017-04-04 10:57:22
original
1766 Les gens l'ont consulté



La fonction finale de DOM et SAX est de nous permettre d'utiliser des langages tels que Java JavaScript pour obtenir des nœuds, du texte, des attributs et d'autres informations dans des fichiers XML.

Cet article est cité d'autres blogs. Le contenu est facile à comprendre. Afin de gagner du temps, je l'ai copié directement. Il existe généralement deux façons d'analyser XML en JAVA, DOM et SAX. Bien que DOM soit une norme du W3C et fournisse une méthode d'analyse standard, son efficacité d'analyse a toujours été insatisfaisante, car lors de l'utilisation de DOM pour analyser XML, l'analyseur lit l'intégralité du document et construit une structure arborescente résidant en mémoire (arborescence de nœuds). ), votre code peut alors utiliser l'interface standard du DOM pour manipuler la structure arborescente. Mais dans la plupart des cas, nous ne sommes intéressés que par une partie du document, et il n'est pas nécessaire d'analyser d'abord l'intégralité du document, et il est également très long d'indexer certaines des données dont nous avons besoin à partir du nœud racine de l'arborescence des nœuds. .

SAX est une alternative à l'analyse XML. Comparé au modèle objet de document DOM, SAX constitue un moyen plus rapide et plus léger de lire et de manipuler des données XML. SAX vous permet de traiter un document au fur et à mesure de sa lecture, vous n'avez donc pas besoin d'attendre que l'intégralité du document soit stockée avant d'agir. Cela n'implique pas les frais généraux et les sauts conceptuels nécessaires au DOM. L'API SAX est une API basée sur les événements adaptée au traitement des flux de données, c'est-à-dire au traitement séquentiel des données au fur et à mesure des flux de données. L'API SAX


vous avertira lorsque certains événements se produisent pendant l'analyse de votre document. Les données que vous n'enregistrez pas seront supprimées lorsque vous y répondrez.


Ce qui suit est un exemple d'analyse XML SAX (un peu long, car toutes les méthodes de traitement des événements SAX sont annotées en détail. Il existe quatre interfaces principales pour le traitement des événements). dans l'API SAX, il s'agit respectivement de ContentHandler, DTDHandler, EntityResolver et ErrorHandler. L'exemple suivant est peut-être un peu long. En fait, tant que vous héritez de la classe DefaultHandler et remplacez certaines méthodes de traitement d'événements, vous pouvez également obtenir l'effet de cet exemple. Mais pour avoir une vue d'ensemble, prenons un. regardez toutes les principales méthodes d'analyse des événements dans l'API SAX. (En fait, DefaultHandler implémente les quatre interfaces de gestionnaire d'événements ci-dessus, puis fournit l'implémentation par défaut de chaque méthode abstraite.)


1, interface ContentHandler : réception de documents Interface de gestionnaire pour notifications de contenu logique.

Code de collecte de code Java

'import org.xml.sax.Attributes;

import org.xml.sax.ContentHandler;

import org. xml.sax.Locator;

import org.xml.sax.SAXException;

class MyContentHandler implémente ContentHandler{

StringBuffer jsonStringBuffer;

int frontBlankCount = 0;

public MyContentHandler(){

jsonStringBuffer = new StringBuffer();

}

/*

* Recevoir une notification des données de caractères.

* Dans le DOM, ch[begin:end] est équivalent à la valeur du nœud Text (nodeValue)

*/

@Override

caractères vides publics (char[] ch, int start, int length) lance SAXException {

StringBuffer buffer = new StringBuffer();

for(int i = start ; i < début+longueur ; i++){

switch(ch[i]){

cas '\\\\\\\\\\\\\\\\\\\\ \\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\':buffer.append("\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\ \\\\\\\\\\\\\\\");break;

cas '\\\\\\\\\\\\\ \\\\\\\\\ \\\\\\\\\r':buffer.append("\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\r");break;

case '\\\\\\\\\\ \\\\\\\\\\\\\\\\\\n':buffer.append("\\\\\ \\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\n");pause;

cas' \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\t':buffer.append("\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\t ");break;

case '\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\"':buffer. append("\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\"");pause;

par défaut : buffer.append(ch[i]) ;

}

}

System.out.println(this.toBlankString(this.frontBlankCount )+

">>> caractères ("+length+") : "+buffer.toString());

}


/*

* Recevoir une notification de fin de document.

*/

@Override

public void endDocument() lance SAXException {

System.out.println(this.toBlankString(--this. frontBlankCount)+

">>> document de fin");

}



/*

* Recevoir une notification de fin de document.

* Les significations des paramètres sont les suivantes :

* uri : l'espace de noms de l'élément

* localName : le nom local de l'élément (sans préfixe)

* qName : Nom qualifié de l'élément (avec préfixe)

*

*/

@Override

public void endElement(String uri ,String localName,String qName )

lance SAXException {

System.out.println(this.toBlankString(--this.frontBlankCount)+

">> > élément de fin : " +qName+"("+uri+")");

}


/*

* Fin le mappage de la plage d'URI du préfixe.

*/

@Override

public void endPrefixMapping (Préfixe de chaîne) lève SAXException {

System.out.println(this.toBlankString(-- this.frontBlankCount)+

">>> end prefix_mapping : "+prefix);

}


/*

* Recevez des notifications d'espaces ignorables dans le contenu des éléments.

* La signification des paramètres est la suivante :

* ch : les caractères du document XML

* start : la position de départ dans le tableau

* longueur : à partir du tableau Le nombre de caractères lus dans

*/

@Override

public void ignorableWhitespace(char[] ch, int start, int length) < 🎜>switch(ch [i]){

cas '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\\\\\\\\\\\\\\\\\\\\\\\':buffer.append("\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\ \\\\");break;

case '\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\r' :buffer.append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\ \\\\\\\\\\\\\\\\\r");break;

cas '\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\n':buffer.append("\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\n") ;break;

case '\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\t':buffer.append( "\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\t");pause;

case '\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\"':buffer.append("\\\\ \\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\"");break;

par défaut : tampon .append(ch[i]);

}

}

System.out.println(this.toBlankString(this.frontBlankCount)+">>> ; espaces ignorables("+length+") : "+buffer.toString());

}

/*

* Recevoir une notification des instructions de traitement.

* Les significations des paramètres sont les suivantes :


* cible : cible de l'instruction de traitement

* données : données de l'instruction de traitement, si elles ne sont pas fournies, elles sont nulles.

*/

@Override

public void traitementInstruction (String target,String data)

lance SAXException {

System.out .println(this.toBlankString(this.frontBlankCount)+">>> instruction de processus : (cible = \\\\\\\\\\\\\\\\\\\\\\\\ \ \\\\\\""

+target+"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ",données = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\""+données+"\\\\\\\\\ \\\\\ \\\\\\\\\\\\\\\\\\")");

}

/*

* Reçoit un objet utilisé pour trouver l'origine des événements du document SAX.

* La signification des paramètres est la suivante :


* localisateur : Un objet qui peut renvoyer l'emplacement de n'importe quel événement de document SAX

*/

@Override

public void setDocumentLocator(Localisateur de localisateur) {

System.out.println(this.toBlankString(this.frontBlankCount)+

">>> ; set document_locator : (lineNumber = " +locator.getLineNumber()

+", columnNumber = "+locator.getColumnNumber()

+", systemId = "+locator.getSystemId()

+" ,publicId = "+locator.getPublicId()+")");

}

/*

* Recevez des notifications des entités ignorées.

* La signification des paramètres est la suivante :


* name : Le nom de l'entité à ignorer. S'il s'agit d'une entité paramètre, le nom commencera par '%',

* S'il s'agit d'un sous-ensemble DTD externe, ce sera la chaîne "[dtd]"

*/

@Override

public void skippedEntity(String name ) lance SAXException {

System.out.println(this.toBlankString(this.frontBlankCount)+

">>> skipped_entity : "+name);

}


/*

* Recevoir une notification du début d'un document.

*/

@Override

public void startDocument() lance SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++) +

">>> début du document ");

}


/*

* Recevoir une notification du début d'un élément.

* Les significations des paramètres sont les suivantes :

* uri : l'espace de noms de l'élément

* localName : le nom local de l'élément (sans préfixe)

* qName : Nom qualifié de l'élément (avec préfixe)

* atts : Collection d'attributs de l'élément

*/

@Override

public void startElement(String uri , String localName, String qName,

Attributes atts) lance SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+

">> ;> élément de début : "+qName+"("+uri+")");

}


/*

* Démarrez le mappage de la portée de l'espace de noms de l'URI du préfixe.

* Les informations de cet événement ne sont pas nécessaires au traitement régulier de l'espace de noms :

* Lorsque la fonctionnalité http://xml.org/sax/features/namespaces est vraie (par défaut),

* Le lecteur XML SAX remplacera automatiquement les préfixes dans les noms d'éléments et d'attributs.

* Les significations des paramètres sont les suivantes :

* préfixe : préfixe

* uri : espace de noms

*/

@Override

public void startPrefixMapping(String prefix,String uri)

lance une exception SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+

">>> start prefix_mapping : xmlns:"+prefix+" = "

+"\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\""+uri+"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"");


}


chaîne privée toBlankString (compte int){

tampon StringBuffer = nouveau StringBuffer ( );

for(int i = 0;i

buffer.append(" " ");

return buffer.toString();

}


}'



2, interface DTDHandler : réception et interface de gestionnaire de notification DTD pour les événements associés

Code de collection de code Java

'import org.xml.sax.DTDHandler;

import org.xml.sax.SAXException ;


classe publique MyDTDHandler implémente DTDHandler {


/*

* Recevoir une notification d'événement de déclaration d'annotation .

* La signification des paramètres est la suivante :

* name - le nom de l'annotation - l'identifiant public de l'annotation, ou null s'il n'est pas fourni. 🎜>* systemId - L'identifiant système de l'annotation, ou null s'il n'est pas fourni

*/

@Override

public void notationDecl(String name. , String publicId, String systemId)

lance SAXException {

System.out.println(">>> notation declare : (name = "+name

+",systemId = "+publicId

+",publicId = "+systemId+")");

}

/ *


* Recevez une notification des événements de déclaration d'entité non résolus.

* La signification des paramètres est la suivante :

* nom - le nom de l'entité non résolue.

* publicId - L'identifiant public de l'entité, ou null s'il n'est pas fourni.

* systemId - L'identifiant système de l'entité.

* notationName - le nom de l'annotation associée.

*/

@Override

public void unparsedEntityDecl(String name,

String publicId,

String systemId,

String notationName) lance SAXException {

System.out.println(">>> entité non analysée déclare : (name = "+name

+",systemId = " +publicId

+",publicId = "+systemId

+",notationName = "+notationName+")");

}

}'



3. Interface EntityResolver : C'est l'interface de base pour analyser les entités.


Code de collecte de code Java

'import java.io.IOException;

import org.xml.sax.EntityResolver;


import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

classe publique MyEntityResolver implémente EntityResolver {


/*


* Permet à l'application de résoudre des entités externes.

* L'analyseur appellera cette méthode avant d'ouvrir toute entité externe (sauf les entités de document de niveau supérieur)

* La signification des paramètres est la suivante :

* publicId : l'entité externe référencée. L'identifiant public, ou null s'il n'est pas fourni.

* systemId : L'identifiant système de l'entité externe référencée.

* Renvoie :

* Un objet InputSource décrivant la nouvelle source d'entrée, ou null,

* pour demander à l'analyseur d'ouvrir une connexion URI régulière à l'identifiant du système.

*/

@Override

public InputSource solveEntity(String publicId, String systemId)

lance SAXException, IOException {

retour null;

}


}


4, interface ErrorHandler : est le gestionnaire d'erreurs de base interface.

Code de collecte de code Java

importer org.xml.sax.ErrorHandler;

importer org.xml.sax.SAXException;

importer org.xml .sax.SAXParseException;


classe publique MyErrorHandler implémente ErrorHandler {


/*

* Recevoir une notification des erreurs récupérables

*/

@Override

public void error(SAXParseException e) lève SAXException {

System.err.println (" Erreur ("+e.getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


/*

* Recevez des notifications d'erreurs irrécupérables.

*/

@Override

public void fatalError(SAXParseException e) lance SAXException {

System.err.println("FatalError ("+e .getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


/*

* Recevez des notifications d'erreurs irrécupérables.

*/

@Override

public void warn(SAXParseException e) renvoie SAXException {

System.err.println("Warning ("+e .getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


}



La méthode principale de la classe Test imprime les informations sur les événements lors de l'analyse de books.xml.

Code de collecte de code Java

importer java.io.FileNotFoundException;

importer java.io.FileReader;

importer java.io.IOException;


importer org.xml.sax.ContentHandler;

importer org.xml.sax.DTDHandler;

importer org.xml.sax .EntityResolver;

importer org.xml.sax.ErrorHandler;

importer org.xml.sax.InputSource;

importer org.xml.sax.SAXException;

importer org.xml.sax.XMLReader;

importer org.xml.sax.helpers.XMLReaderFactory;



test de classe publique {


public static void main(String[] args) lance SAXException,

FileNotFoundException, IOException {

//Créer un gestionnaire pour gérer les événements liés au contenu du document

ContentHandler contentHandler = new MyContentHandler();

//Créer un gestionnaire pour gérer les événements d'erreur

ErrorHandler errorHandler = new MyErrorHandler();

//Créer un gestionnaire pour gérer les événements liés à la DTD

DTDHandler dtdHandler = new MyDTDHandler();

//Créer un analyseur d'entité

EntityResolverentityResolver = new MyEntityResolver();


//Créer un analyseur XML (lire et analyser XML via SAX)

Lecteur XMLReader = XMLReaderFactory.createXMLReader();

/*

* Définir les fonctionnalités liées à l'analyseur

* http://xml.org/sax/features/validation = true Indique que la fonction de vérification est activée

* http://xml.org/sax/features/namespaces = true indique que la fonctionnalité d'espace de noms est activée

*/

reader. setFeature(" http://xml.org/sax/features/validation",true);

reader.setFeature("http://xml.org/sax/features/namespaces",true);

//Définissez le gestionnaire de l'analyseur XML pour gérer les événements liés au contenu du document

reader.setContentHandler(contentHandler);

//Définissez le gestionnaire de l'analyseur XML pour gérer les événements d'erreur

reader.setErrorHandler(errorHandler);

//Définissez le gestionnaire de l'analyseur XML pour gérer les événements liés à la DTD

reader.setDTDHandler(dtdHandler);

//Définir l'analyseur d'entités de l'analyseur XML

reader.setEntityResolver(entityResolver);

//Analyser le document books.xml

reader.parse(new InputSource( new FileReader("books.xml")));

}


}'



Le contenu du fichier books.xml est le suivant :


Code XML Code de collection







Penser en JAVA




Core JAVA2




Introduction au C++




La sortie de la console est la suivante :


>>> set document_locator : (lineNumber = 1, columnNumber = 1, systemId = null, publicId = null)

>>> démarrer le document

Erreur (2,7) : Le document n'est pas valide : aucune grammaire trouvée.

Erreur (2,7) : L'élément racine du document "books", doit correspondre à la racine DOCTYPE "null".

>>> start prefix_mapping : xmlns: = "http://test.org/books"

> >> élément de départ : livres(http://test.org/books)

>>> \\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\ \t

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément de démarrage : livre(http://test.org/books)

>>> caractères (3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> élément de démarrage : nom(http://test.org/books)

>>> caractères(16) : Penser en JAVA

>>> élément de fin : nom(http://test.org/books)

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément final : livre(http://test.org/books)

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément de démarrage : livre(http://test.org/books)

>>> caractères (3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> élément de démarrage : nom(http://test.org/books)

>>> caractères (10) : Core JAVA2

>>> élément de fin : nom(http://test.org/books)

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément final : livre(http://test.org/books)

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément de démarrage : livre(http://test.org/books)

>>> caractères (3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> élément de démarrage : nom(http://test.org/books)

>>> caractères (10) : introduction C++

>>> élément de fin : nom(http://test.org/books)

>>> caractères (2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> élément final : livre(http://test.org/books)

>>> caractères (1) : \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n

>>> élément final : livres(http://test.org/books)

>>> fin prefix_mapping :

>>> document de fin  

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal