przejście do zawartości
zpr c++ quick reference
Narzędzia użytkownika
Zarejestruj się!
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Zarejestruj się!
Ostatnie zmiany
Menadżer multimediów
Indeks
Ślad:
xerces_dom
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== biblioteka dla XML: Xerces (DOM) ===== **Autor:** //[[kmioduszewski@polibuda.info|Krzysztof Mioduszewski]] 2008/04/14 23:59//\\ \\ Xerces-C++ DOM jest częścią Xerces-C++ API zaprojektowanego do współpracy z plikami w formacie XML. API umożliwia parsowania, manipulowanie, walidowanie oraz generowanie poprawnych dokumentów. \\ \\ Biblioteka DOM jest implementacją następujących rekomendacji W3C: * [[http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/|Document Object Model (DOM) Level 1 Specification]] * [[http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/|Document Object Model (DOM) Level 2 Core Specification]] * [[http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/|Document Object Model (DOM) Level 2 Traversal and Range Specification]] Oraz zawiera częściową implementację (opartą o W3C Working Draft 09 April 2002) : * [[http://www.w3.org/TR/2002/WD-DOM-Level-3-Core-20020409/|Document Object Model (DOM) Level 3 Core Specification]] * [[http://www.w3.org/TR/2002/WD-DOM-Level-3-ASLS-20020409/|Document Object Model (DOM) Level 3 Abstract Schemas and Load and Save Specification]] \\ Więcej informacji na stronie projektu http://xerces.apache.org/xerces-c/. Na stronie znajdują się źródła, oraz skompilowane wersje biblioteki na różne platformy. Kompletna instrukcja instalacji na różnych platformach znajduje się [[http://xerces.apache.org/xerces-c/install.html|tutaj]]. ===== Informacje wstępne ===== Nagłówki, które powinniśmy dołączyć w przypadku pisania typowych aplikacji korzystających z Xerces DOM znajdują się poniżej: <code cpp> #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> </code> Xerces posiada własny typ znakowy ''XMLCh'', który jest używany zamiast ''char'' i ''std::string''. Do konwersji pomiędzy typami ''char*'' a ''XMLCh*'' (w obie strony) używana jest funkcja ''XMLString::transcode()''. Pamięć zaalokowaną na łańcuchy należy zwalniać za pomocą funkcji ''XMLString::release()''. Przed użyciem jakichkolwiek klas Xerces konieczne jest wywołanie metody ''XMLPlatformUtils::Initialize()''. Po zakończeniu korzystania z Xerces powinno się wywołać ''XMLPlatformUtils::Terminate()''. Poniżej znajduje się uproszczona struktura programu (warto zwrócić uwagę na uzycie ''transcode()''). <code cpp> #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> // ... #include <iostream> int main() { try { //incjalizacja Xerces-C++ xercesc::XMLPlatformUtils::Initialize(); } catch (const xercesc::XMLException& e) { //konwersja z XMLCh* na char* char* msg = xercesc::XMLString::transcode(e.getMessage()) ; std::cerr << "Init Error: " << msg << std::endl; //zwolnienie pamieci xercesc::XMLString::release(&msg) ; return 1; } // Tutaj korzystamy z mozliwosci Xerces-C++ xercesc::XMLPlatformUtils::Terminate(); return 0; } </code> ===== XercesDOMParser ===== Jest to parser umożliwiający wczytanie do pamięci struktury pliku XML za pomocą metody ''parse()''. Po czym uzyskujemy dostęp do obiektu ''DOMDocument'', po którym możemy poruszać się wykorzystując zaimplementowane w zgodzie z rekomendacjami W3C metody. Poniżej przykładowe fragmenty kodu dotyczącego inicjalizacji i korzystania z ''XercesDOMParser''. <code cpp> xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser(); parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto); //uruchamia walidację, jeżeli dostępne jest DTD (wewnętrzne/zewnętrzne) parser->setDoNamespaces(true); char* xmlFile = "file.xml"; try { parser->parse(xmlFile); } catch( const xercesc::XMLException& e ){ //... } catch( const xercesc::DOMException& e ){ //... } catch (...) { //... } //sprawdzamy czy nie wystąpiły błędy podczas parsowania if(parser->getErrorCount()==0) { xercesc::DOMDocument* XMLdoc = parser->getDocument(); //... } </code> Dobrym pomysłem jest zastosowanie własnego ''ErrorHandler'' do wykrywania błędów składniowych w trakcie parsowania i wyświetlania o nich informacji (typ, miejsce wystąpienia). Najprostszy sposób to zaimplementowanie metod z interfejsu ''HandlerBase'': <code cpp> #include <xercesc/sax/HandlerBase.hpp> class myErrorHandler : xercesc::HandlerBase { void warning( const xercesc::SAXParseException& e ) { char *msg = xercesc::XMLString::transcode(e.getMessage()); std::cout << "warning: " << msg << " | line: " << e.getLineNumber() << std::endl; xercesc::XMLString::release(&msg); } void error( const xercesc::SAXParseException& e ) { // analogicznie jak wyżej } void fatalError( const xercesc::SAXParseException& e ) { // j.w. } void resetErrors() {} }; //... xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser(); parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto); parser->setDoNamespaces(true); xercesc::ErrorHandler* errHandler = (xercesc::ErrorHandler*) new myErrorHandler(); parser->setErrorHandler(errHandler); </code> ===== DOMDocument, operacje na dokumencie===== Gdy dokument zostanie sparsowany bez żadnych błędów możemy swobodnie zacząć na nim pracować wykorzystując zawarte w rekomendacjach metody. Poniżje znajduje się kod przykładowej aplikacji, która wczytuje plik XML, wpisuje jego zawartość na ekran, modyfikuje go, a następnie zapisuje zmiany do pliku.\\ \\ Plik XML - ''notes.xml'', który zostanie wczytany: <code xml> <?xml version="1.0"?> <!DOCTYPE notes SYSTEM "note.dtd"> <notes owner="John Doe"> <note date="21/02/2008"> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note> <note date="12/04/2008"> <from>Jeff</from> <heading>Money</heading> <body>Gimme my money back!</body> </note> </notes> </code> DTD - ''notes.dtd'' <code> <!ELEMENT notes (note+) > <!ATTLIST notes owner CDATA #REQUIRED> <!ELEMENT note (from,heading,body)> <!ATTLIST note date CDATA #REQUIRED> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> </code> Klasy pomocnicze ''support.h'': <code cpp> #include <string> #include <iostream> #include <xercesc/util/XMLString.hpp> #include <xercesc/sax/HandlerBase.hpp> //klasa pomocnicza ułatwiająca współpracę z XMLCh* class UniString { public : UniString(const XMLCh* const str) : cString(xercesc::XMLString::transcode(str)), xmlString(xercesc::XMLString::replicate(str)) {} UniString(const char* const str) : cString(xercesc::XMLString::replicate(str)), xmlString(xercesc::XMLString::transcode(str)) {} UniString(const std::string& str) : cString(xercesc::XMLString::replicate(str.c_str())), xmlString(xercesc::XMLString::transcode(str.c_str())) {} ~UniString() { xercesc::XMLString::release(&cString); xercesc::XMLString::release(&xmlString); } const char* toCString() { return cString; } const XMLCh* toXMLString() { return xmlString; } std::ostream& print(std::ostream& s) const { s << cString; return(s); } private : char* cString; XMLCh* xmlString; }; std::ostream& operator<<( std::ostream& s, const UniString& str ) { return str.print(s); } //klasa pomocnicza przechowująca nazwy tagów oraz atrybutów class docNames { public: const UniString TAG_NOTES; const UniString TAG_NOTE; const UniString TAG_FROM; const UniString TAG_HEADING; const UniString TAG_BODY; const UniString ATTR_OWNER; const UniString ATTR_DATE; docNames() : TAG_NOTES("notes"), TAG_NOTE("note"), TAG_FROM("from"), TAG_HEADING("heading"), TAG_BODY("body"), ATTR_OWNER("owner"), ATTR_DATE("date") {} }; class myErrorHandler : xercesc::HandlerBase { void warning( const xercesc::SAXParseException& e ) { std::cout << "warning: " << UniString(e.getMessage()) << " | line: " << e.getLineNumber() << std::endl; } void error( const xercesc::SAXParseException& e ) { std::cout << "error: " << UniString(e.getMessage()) << " | line: " << e.getLineNumber() << std::endl; } void fatalError( const xercesc::SAXParseException& e ) { std::cout << "fatalError: " << UniString(e.getMessage()) << " | line: " <<e.getLineNumber() << std::endl; } void resetErrors() {} }; </code> ''parser.cpp'' <code cpp> #include "support.h" xercesc::DOMDocument* parseXML() { xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser(); parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto); parser->setDoNamespaces(true); xercesc::ErrorHandler* errHandler = (xercesc::ErrorHandler*) new myErrorHandler(); parser->setErrorHandler(errHandler); UniString src = UniString("dupa.xml"); try { parser->parse(src.toXMLString()); } catch (...) { //... } if(parser->getErrorCount()==0) { return parser->getDocument(); } else { return NULL; } } int main() { try { xercesc::XMLPlatformUtils::Initialize(); } catch (const xercesc::XMLException& e) { std::cerr << UniString(e.getMessage()) << std::endl; return 1; } xercesc::DOMDocument* xmlDoc = parseXML(); if(xmlDoc == NULL) return -1; xercesc::XMLPlatformUtils::Terminate(); int a; std::cin >> a; return 0; } </code> <code cpp> //... xercesc::DOMDocument* XMLdoc = parser->getDocument(); xercesc::DOMElement* root = XMLdoc->getDocumentElement(); //pobieramy nazwę elementu głównego char* rootName = XMLString::transcode(root->getLocalName()); if(root->hasAttributes()) { xercesc::DOMNamedNodeMap* attrMap = root->getAttributes(); //iterujemy sobie po atrybutach for( XMLSize_t i = 0 ; i < attrMap->getLength() ; ++i ) { DOMAttr* attr = dynamic_cast<DOMAttr*>(attrMap->item(ix)); //wykorzystujemy sobie atrybut attr->getName(); //tutaj mamy nazwe attr->getValue(); //wartosc //... } } </code>
xerces_dom.1208217673.txt.gz
· ostatnio zmienione: 2008/04/15 02:01 przez
kmioduszewski
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Do góry