Lecture d'un fichier XML volumineux par la méhode SAX
# 0000000245
ajouté le 28/09/2005 15:05:03 et modifié le 08/11/2005
consulté 14471 fois
Niveau
initié
Version(s) Foxpro : VFP 9.0
Description
Lorsqu'un fichier XML est volumineux (plus de 1 Mo), sa lecture en utilisant XmlToCursor() est lente, voire impossible. Ceci est dû au fait que cette fonction utilise la technique XML-DOM (Document Object Model), c'est à dire que le fichier XML est chargé entièrement en mémoire sous forme d'objets hiérarchisés.
Voici un exemple en VFP utilisant la technique SAX (Simple API for XML) via le composant MSXML.
A noter que le .NET Framework fournit une 3ème méthode de lecture d'un XML : XML Serializer XmlReader. C'est promis, dès que ce sera possible de l'utiliser facilement avec VFP (SEDNA ?), je posterai un exemple !
Code source :
#DEFINE FICHIERXML "c:\tmp\orders.xml"
CLEAR CLOSETABLESall SETPOINTTO"."
*--- création d'un gros fichier XML
WAITWINDOW"Création fichier XML..."NOWAITnoclear
SELECT * ; FROM (_samples+"northwind\orders") ; UNIONALLSELECT * ; FROM orders ; UNIONALLSELECT * ; FROM orders ; UNIONALLSELECT * ; FROM orders ; INTOCURSOR xml
SELECT * ; FROM (_samples+"northwind\orders") ; WHERE.f. ; INTOCURSOR xml READWRITE
LOCAL o as Msxml.SAXXMLReader40
o=CreateObject("Msxml2.SAXXMLReader")
o.contentHandler = CreateObject("SAX","xml")
o.parseURL(FICHIERXML)
? "SAX", Seconds()-t1 *-----
PROCEDURE IVBSAXContentHandler_put_documentlocator(oDoc as Object)
ENDPROC
PROCEDURE IVBSAXContentHandler_documentLocator() AS VARIANT;
HELPSTRING "Receive an object for locating the origin of SAX document events." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_startDocument() AS VOID;
HELPSTRING "Receive notification of the beginning of a document." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_endDocument() AS VOID;
HELPSTRING "Receive notification of the end of a document." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_startPrefixMapping(strPrefix ASSTRING @, strURI ASSTRING @) AS VOID;
HELPSTRING "Begin the scope of a prefix-URI Namespace mapping." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_endPrefixMapping(strPrefix ASSTRING @) AS VOID;
HELPSTRING "End the scope of a prefix-URI mapping." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_startElement(strNamespaceURI ASSTRING @, strLocalName ASSTRING @, strQName ASSTRING @, oAttributes AS VARIANT) AS VOID;
HELPSTRING "Receive notification of the beginning of an element." * add user code here
ENDPROC
PROCEDURE IVBSAXContentHandler_endElement(strNamespaceURI ASSTRING @, strLocalName ASSTRING @, strQName ASSTRING @) AS VOID;
HELPSTRING "Receive notification of the end of an element." * add user code here
ENDPROC
PROCEDURE IVBSAXContentHandler_characters(strChars ASSTRING @) AS VOID;
HELPSTRING "Receive notification of character data." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_ignorableWhitespace(strChars ASSTRING @) AS VOID;
HELPSTRING "Receive notification of ignorable whitespace in element content." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_processingInstruction(strTarget ASSTRING @, strData ASSTRING @) AS VOID;
HELPSTRING "Receive notification of a processing instruction." * add user code here ENDPROC
PROCEDURE IVBSAXContentHandler_skippedEntity(strName ASSTRING @) AS VOID;
HELPSTRING "Receive notification of a skipped entity." * add user code here ENDPROC
ENDDEFINE
Commentaires
le 28/09/2005, FredA a écrit : Serializer... j'ai vu trainer quelque part la création d'un objet en VFP à partir d'une chaine csv ... dès que je retrouve, je te dis ;)
le 28/09/2005, Thierry a écrit : En fait, le remplacant de SAX dans .NET dont je voulais parler, c'est XmlReader.
XMLSerializer, c'est une évolution de XMLDOM (XML<->objets )
le 28/09/2005, Francis Faure a écrit : c cool ton truc
le 29/09/2005, Thierry a écrit : Pour le fun, voici un parser XML ultra rapide et 100% Fox :
PUBLIC ARRAY aTab(1) ALines(aTab,FileToStr(FICHIERXML),1+4+16,">",Chr(9),Chr(13),Chr(10)) FOR EACH ligne IN aTab i=At("</",m.ligne) IF i > 0 attribut = Substr(m.ligne,i+2,Len(m.ligne)-i-2) valeur = Left(m.ligne,i-1) ... ENDIF ENDFOR
le 18/02/2009, Olivier Hamou a écrit : Bonsoir thierry, Aurais tu plus d'infos sur ton parser 100% Fox ? Est ce une solution aussi stable que Sax ?
Olivier,
le 18/02/2009, Thierry a écrit : C'est seulement une solution très simpliste.
Serializer... j'ai vu trainer quelque part la création d'un objet en VFP à partir d'une chaine csv ...
dès que je retrouve, je te dis ;)