Narzędzia użytkownika

Narzędzia witryny


xerces_dom

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
xerces_dom [2008/04/15 02:01]
kmioduszewski
xerces_dom [2008/04/16 15:33] (aktualna)
kmioduszewski
Linia 1: Linia 1:
 ====== biblioteka dla XML: Xerces (DOM) ===== ====== biblioteka dla XML: Xerces (DOM) =====
- **Autor:** //[[kmioduszewski@polibuda.info|Krzysztof Mioduszewski]] 2008/04/14 23:59//\\ \\ +**Autor** //Krzysztof Mioduszewski ​- k.mioduszewski@stud.elka... ​2008/04/16 02:12//\\ \\ 
 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. 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.
 \\ \\  ​ \\ \\  ​
Linia 139: Linia 139:
  
 </​code> ​ </​code> ​
 +
 +
 +
 +
  
  
Linia 159: Linia 163:
  
 ===== DOMDocument,​ operacje na dokumencie===== ===== 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.\\ \\ +Gdy dokument zostanie sparsowany bez żadnych błędów możemy swobodnie zacząć na nim pracować wykorzystując zawarte w rekomendacjach metody. Poniżej znajduje się kod przykładowej aplikacji, która wczytuje plik XML, wypisuje ​jego zawartość na ekran, modyfikuje go, a następnie zapisuje zmiany do pliku.\\ \\ 
 Plik XML - ''​notes.xml'',​ który zostanie wczytany: Plik XML - ''​notes.xml'',​ który zostanie wczytany:
 <code xml> <code xml>
Linia 191: Linia 195:
 #include <​string>​ #include <​string>​
 #include <​iostream>​ #include <​iostream>​
 +#include <​stdexcept>​
 #include <​xercesc/​util/​XMLString.hpp>​ #include <​xercesc/​util/​XMLString.hpp>​
 #include <​xercesc/​sax/​HandlerBase.hpp>​ #include <​xercesc/​sax/​HandlerBase.hpp>​
- +#include <​xercesc/​util/​PlatformUtils.hpp>​ 
 +#include <​xercesc/​dom/​DOM.hpp>​  
 +#include <​xercesc/​parsers/​XercesDOMParser.hpp>​ 
 +#include <​xercesc/​framework/​LocalFileFormatTarget.hpp>​ 
 +#include <​xercesc/​framework/​StdOutFormatTarget.hpp>​ 
 //klasa pomocnicza ułatwiająca współpracę z XMLCh* //klasa pomocnicza ułatwiająca współpracę z XMLCh*
 class UniString { class UniString {
 +private :
 + char* ​  ​cString;​
 + XMLCh* ​ xmlString;
 +
 public : public :
  UniString(const XMLCh* const str)   UniString(const XMLCh* const str) 
Linia 221: Linia 235:
  }  }
    
- const char* toCString() { return cString; } + const char* toCString() ​const { return cString; } 
- const XMLCh* toXMLString() ​ { return xmlString; }+ const XMLCh* toXMLString() ​const { return xmlString; }
    
  std::​ostream&​ print(std::​ostream&​ s) const   std::​ostream&​ print(std::​ostream&​ s) const 
Linia 230: Linia 244:
  }  }
    
-private : +
- char* ​  ​cString;​ +
- XMLCh* ​ xmlString;​ +
- +
 }; };
    
Linia 239: Linia 250:
    
 //klasa pomocnicza przechowująca nazwy tagów oraz atrybutów ​ //klasa pomocnicza przechowująca nazwy tagów oraz atrybutów ​
-class docNames ​{+class DocNames ​{
 public: public:
  const UniString TAG_NOTES;  const UniString TAG_NOTES;
Linia 250: Linia 261:
  const UniString ATTR_DATE;  const UniString ATTR_DATE;
    
- docNames()+ DocNames()
  :  :
  TAG_NOTES("​notes"​),​  TAG_NOTES("​notes"​),​
Linia 265: Linia 276:
 class myErrorHandler : xercesc::​HandlerBase { class myErrorHandler : xercesc::​HandlerBase {
  void warning( const xercesc::​SAXParseException&​ e ) {   void warning( const xercesc::​SAXParseException&​ e ) { 
- std::cout << "​warning:​ " << UniString(e.getMessage())+ std::cerr << "​warning:​ " << UniString(e.getMessage())
    << " | line: " << e.getLineNumber() << std::endl;    << " | line: " << e.getLineNumber() << std::endl;
  }  }
  void error( const xercesc::​SAXParseException&​ e ) {  void error( const xercesc::​SAXParseException&​ e ) {
- std::cout << "​error:​ " << UniString(e.getMessage()) ​+ std::cerr << "​error:​ " << UniString(e.getMessage()) ​
  << " | line: " << e.getLineNumber() << std::endl;  << " | line: " << e.getLineNumber() << std::endl;
  }  }
  void fatalError( const xercesc::​SAXParseException&​ e ) {  void fatalError( const xercesc::​SAXParseException&​ e ) {
- std::cout << "​fatalError:​ " << UniString(e.getMessage())  ​+ std::cerr << "​fatalError:​ " << UniString(e.getMessage())  ​
  << " | line: " <<​e.getLineNumber() << std::endl;  << " | line: " <<​e.getLineNumber() << std::endl;
  }  }
Linia 279: Linia 290:
 }; };
 </​code>​ </​code>​
-''​parser.cpp'' ​FIXME+''​DOMtest.h'' ​- zawiera klasę DOMtest, prezentującą możliwości korzystania biblioteki DOM.
 <code cpp> <code cpp>
 #include "​support.h"​ #include "​support.h"​
  
-xercesc::​DOMDocument* parseXML() ​+class DOMtest ​
- xercesc::XercesDOMParser* parser = new xercesc::​XercesDOMParser()+private:  
- parser->​setValidationScheme(xercesc::​XercesDOMParser::​Val_Auto); ​  + std::string filename
- parser->​setDoNamespaces(true)  + xercesc::​XercesDOMParser parser; 
-  + DocNames names
- xercesc::​ErrorHandler* errHandler = (xercesc::​ErrorHandler*) new myErrorHandler()+ bool loaded;
- parser->​setErrorHandler(errHandler);+
  
- UniString src UniString("dupa.xml"); + DOMtest(const DOMtest&​);​ 
- try { +public: 
- parser->parse(src.toXMLString());+ DOMtest(std::​string f)  
 + :  
 + filename(f),​  
 + parser(),​ 
 + names(),​ 
 + loaded(false) 
 + { }; 
 + 
 + void init() throw( std::​runtime_error ) 
 +
 + parser.setValidationScheme(xercesc::​XercesDOMParser::​Val_Auto); ​    
 + parser.setDoNamespaces(true); ​   
 +  
 + xercesc::​ErrorHandler* errHandler ​= (xercesc::​ErrorHandler*) new myErrorHandler();​ 
 + parser.setErrorHandler(errHandler); 
 +  
 + try { 
 + parser.parse(filename.c_str()); 
 + } catch(xercesc::​XMLException&​ e){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​ 
 + }catch( const xercesc::​DOMException&​ e ){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​  
 +
 +  
 + if(parser.getErrorCount()!=0)  
 + throw(std::​runtime_error("​..."​));
  }  }
- catch (...) { +  
- //...+ //funkcja zawierający przykładowy sposób pobiernia  
 + //​informacji z dokumentu ​(bonus wyswietlanie ich) 
 + std::​ostream&​ print(std::​ostream&​ s) throw(std::​runtime_error) ​ { 
 + s << "MY NOTES: " << std::​endl;​ 
 + try { 
 + //​bierzmy sobie dokumenty 
 + xercesc::​DOMDocument* xmlDoc = parser.getDocument();​ 
 + 
 + //​bierzemy sobie element główny 
 + xercesc::​DOMElement* root = xmlDoc->​getDocumentElement();​ 
 +  
 + if(root == NULL) 
 + throw(std::​runtime_error("​Empty Document"​));​ 
 + 
 + //​pobieramy wartość atrybutu owner 
 + //names.ATTR_OWNER.toXMLString() <- zwraca XMLCh* "​owner";​ -> support.h 
 + UniString owner(root->​getAttribute(names.ATTR_OWNER.toXMLString()));​ 
 + s << "​owner:​ " << owner << std::​endl;​ 
 + 
 + //​pobieramy wszystkie elementy '​note'​ 
 + xercesc::​DOMNodeList* notesElements = root->​getElementsByTagName(names.TAG_NOTE.toXMLString());​ 
 + 
 + for( XMLSize_t i = 0; i < notesElements->​getLength();​ ++i) { 
 + s << "note no. " << i+1 << " "; 
 + 
 + //bierzmy sobie node 
 + xercesc::​DOMNode* node = notesElements->​item(i);​ 
 +  
 + //​konwersja na DOMElement, mogę sobie na to pozwolić gdyż znam, 
 + //​całą strukturę dokumentu, w przypadku nie znania wypadałoby sprawdzić 
 + //​aczkolwiek dynamic_cast rzuci wyjatke w razie problemów 
 + xercesc::​DOMElement* domElement = dynamic_cast<​xercesc::​DOMElement*>​(node);​ 
 +  
 + //​pobieram datę 
 + UniString date(domElement->​getAttribute(names.ATTR_DATE.toXMLString()));​ 
 + s << "date: " << date << std::​endl;​ 
 +  
 + //​pobiorę sobie "​bezposrednio"​ zawartość <​form></​form>​ 
 + //nie jest to może tak "​bezpośrednie"​ jak npw Javascript ;) 
 + UniString from(domElement->​getElementsByTagName(names.TAG_FROM.toXMLString())->​item(0)->​getTextContent());​ 
 + s << " From: " << from << std::endl;  
 + 
 + //teraz kolejne elementy 
 + UniString heading(domElement->​getElementsByTagName(names.TAG_HEADING.toXMLString())->​item(0)->​getTextContent());​ 
 + s << " Heading: " << heading << std::​endl;​ 
 + 
 + UniString body(domElement->​getElementsByTagName(names.TAG_BODY.toXMLString())->​item(0)->​getTextContent());​ 
 + s << " Body: " << std::endl << " ​   " << body << std::endl << std::​endl;​ 
 +
 + 
 + } catch(xercesc::​XMLException&​ e){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​ 
 + } catch( const xercesc::​DOMException&​ e ){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​  
 + }  
 + return(s) ;
  }  }
-  +  
- if(parser->​getErrorCount()==0{ + //tworzymy nową notkę i dopinamy ją do drzewa dokumentu 
- return parser->getDocument(); + void modify() throw(std::​runtime_error)  
-else +
- return NULL;+ try { 
 + //tresc notki 
 + UniString date("​16/​04/​2008"​);​ 
 + UniString from("​Cassius"​);​ 
 + UniString heading("​!!!"​);​ 
 + UniString body("​Nice try, Zarflax!"​);​ 
 + 
 + //aby tworzyć nowe elemnty potrzebujemy DOMDocument 
 + xercesc::​DOMDocument* xmlDoc = parser.getDocument();​ 
 +  
 + //​tworzymy nowy element <​note></​note>​ 
 + xercesc::​DOMElement* noteElement = xmlDoc->createElement(names.TAG_NOTE.toXMLString()); 
 +  
 + //​tworzymy atrybut date 
 + xercesc::​DOMAttr* noteElementDate ​xmlDoc->​createAttribute(names.ATTR_DATE.toXMLString());​ 
 + //​ustawiamy wartosc atrybutu date 
 + noteElementDate->​setValue(date.toXMLString());​ 
 + //​przypinamy atrybut date do elementu note 
 + noteElement->​setAttributeNode(noteElementDate);​ 
 +  
 + //​tworzymy kolejne elementy i przypominamy do notki 
 + xercesc::​DOMElement* noteFromElement ​xmlDoc->​createElement(names.TAG_FROM.toXMLString()); 
 + //​ustawiamy tresc elementu <​from></​from>​ 
 + noteFromElement->setTextContent(from.toXMLString()); 
 + noteElement->​appendChild(noteFromElement);​ 
 + 
 + xercesc::​DOMElement* noteHeadingElement = xmlDoc->​createElement(names.TAG_HEADING.toXMLString());​ 
 + noteHeadingElement->​setTextContent(heading.toXMLString());​ 
 + noteElement->​appendChild(noteHeadingElement);​ 
 + 
 + xercesc::​DOMElement* noteBodyElement = xmlDoc->​createElement(names.TAG_BODY.toXMLString());​ 
 + noteBodyElement->​setTextContent(body.toXMLString());​ 
 + noteElement->​appendChild(noteBodyElement);​ 
 +  
 + //​dopinamy kompletną notkę elementu <​notes></​notes>​ 
 + xmlDoc->​getDocumentElement()->​appendChild(noteElement);​ 
 + 
 + catch(xercesc::​XMLException&​ e){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​ 
 + } catch( const xercesc::​DOMException&​ e ){ 
 + UniString eMsg(e.getMessage()); 
 + throw(std::​runtime_error(eMsg.toCString()));​  
 + }
  }  }
-}+ 
 + void write(std::​string filename) throw(std::​runtime_error) { 
 + try { 
 + //​konieczne do wykorzystania przy zapisie pliku 
 + xercesc::​XMLFormatTarget* file = new xercesc::​LocalFileFormatTarget(UniString(filename).toXMLString());​ 
 +  
 + //obiekt wykorzystywana do zapisu 
 + xercesc::​DOMWriter* domWriter = parser.getDocument()->​getImplementation()->​createDOMWriter();​ 
 +  
 + //jezeli mamy możliwość ustawiamy przyjazne dla człowieka formatowanie 
 + if(domWriter->​canSetFeature(xercesc::​XMLUni::​fgDOMWRTFormatPrettyPrint,​true)){ 
 + domWriter->​setFeature(xercesc::​XMLUni::​fgDOMWRTFormatPrettyPrint,​true);​ 
 + } 
 +  
 + //​zapis 
 + domWriter->​writeNode(file,​*parser.getDocument());​  
 + 
 + delete(file);​ 
 + } catch(xercesc::​XMLException&​ e){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​ 
 + } catch( const xercesc::​DOMException&​ e ){ 
 + UniString eMsg(e.getMessage());​ 
 + throw(std::​runtime_error(eMsg.toCString()));​  
 + }  
 +
 +}; 
 +</​code>​ 
 +plik testujący ''​main.cpp''​ 
 +<code cpp> 
 +#include "​DOMtest.h"​
  
 int main() { int main() {
Linia 315: Linia 482:
  }  }
    
- xercesc::DOMDocument* xmlDoc = parseXML(); + try { 
- if(xmlDoc == NULL+ DOMtest DOM("​notes.xml"​);​ 
- return -1;+ //​incjacja prasera itp. 
 + DOM.init();​ 
 + //​pobieranie wartości, wydruk na ekranie 
 + DOM.print(std::cout); 
 + //dodanie notki 
 + DOM.modify(); 
 + //zapisu do pliku 
 + DOM.write("​notes2.xml"​);
  
- + } catch(std::​runtime_error&​ e) { 
 + std::cerr << e.what() << std::​endl;​ 
 + std::cerr << "​Exiting"​ << std::​endl;​ 
 +
 +
  xercesc::​XMLPlatformUtils::​Terminate();​  xercesc::​XMLPlatformUtils::​Terminate();​
    
- int a; 
- std::cin >> a; 
  return 0;  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>​ </​code>​
xerces_dom.1208217714.txt.gz · ostatnio zmienione: 2008/04/15 02:01 przez kmioduszewski