XML file: sample.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
   <ApplicationSettings
           option_a = "10"
           option_b = "24"
           >
   </ApplicationSettings>
   <OtherStuff
           option_x = "500"
           >
   </OtherStuff>
</root>


Include file: parser.hpp

#ifndef XML_PARSER_HPP
#define XML_PARSER_HPP
/**
 *  @file
 *  Class "GetConfig" provides the functions to read the XML data.
 *  @version 1.0
 */
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMNodeIterator.hpp>
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMText.hpp>

#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLUni.hpp>

#include <string>
#include <stdexcept>

// Error codes

enum {
   ERROR_ARGS = 1, 
   ERROR_XERCES_INIT,
   ERROR_PARSE,
   ERROR_EMPTY_DOCUMENT
};

class GetConfig
{
public:
   GetConfig();
  ~GetConfig();
   void readConfigFile(std::string&) throw(std::runtime_error);
 
   char *getOptionA() { return m_OptionA; };
   char *getOptionB() { return m_OptionB; };

private:
   xercesc::XercesDOMParser *m_ConfigFileParser;
   char* m_OptionA;
   char* m_OptionB;

   // Internal class use only. Hold Xerces data in UTF-16 SMLCh type.

   XMLCh* TAG_root;

   XMLCh* TAG_ApplicationSettings;
   XMLCh* ATTR_OptionA;
   XMLCh* ATTR_OptionB;
};
#endif


C++ Program file: parser.cpp

#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <list>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "parser.hpp"

using namespace xercesc;
using namespace std;

/**
 *  Constructor initializes xerces-C libraries.
 *  The XML tags and attributes which we seek are defined.
 *  The xerces-C DOM parser infrastructure is initialized.
 */

GetConfig::GetConfig()
{
   try
   {
      XMLPlatformUtils::Initialize();  // Initialize Xerces infrastructure
   }
   catch( XMLException& e )
   {
      char* message = XMLString::transcode( e.getMessage() );
      cerr << "XML toolkit initialization error: " << message << endl;
      XMLString::release( &message );
      // throw exception here to return ERROR_XERCES_INIT
   }

   // Tags and attributes used in XML file.
   // Can't call transcode till after Xerces Initialize()
   TAG_root        = XMLString::transcode("root");
   TAG_ApplicationSettings = XMLString::transcode("ApplicationSettings");
   ATTR_OptionA = XMLString::transcode("option_a");
   ATTR_OptionB = XMLString::transcode("option_b");

   m_ConfigFileParser = new XercesDOMParser;
}

/**
 *  Class destructor frees memory used to hold the XML tag and 
 *  attribute definitions. It als terminates use of the xerces-C
 *  framework.
 */

GetConfig::~GetConfig()
{
   // Free memory

   delete m_ConfigFileParser;
   if(m_OptionA)   XMLString::release( &m_OptionA );
   if(m_OptionB)   XMLString::release( &m_OptionB );

   try
   {
      XMLString::release( &TAG_root );

      XMLString::release( &TAG_ApplicationSettings );
      XMLString::release( &ATTR_OptionA );
      XMLString::release( &ATTR_OptionB );
   }
   catch( ... )
   {
      cerr << "Unknown exception encountered in TagNamesdtor" << endl;
   }

   // Terminate Xerces

   try
   {
      XMLPlatformUtils::Terminate();  // Terminate after release of memory
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );

      cerr << "XML ttolkit teardown error: " << message << endl;
      XMLString::release( &message );
   }
}

/**
 *  This function:
 *  - Tests the access and availability of the XML configuration file.
 *  - Configures the xerces-c DOM parser.
 *  - Reads and extracts the pertinent information from the XML config file.
 *
 *  @param in configFile The text string name of the HLA configuration file.
 */

void GetConfig::readConfigFile(string& configFile)
        throw( std::runtime_error )
{
   // Test to see if the file is ok.

   struct stat fileStatus;

   int iretStat = stat(configFile.c_str(), &fileStatus);
   if( iretStat == ENOENT )
      throw ( std::runtime_error("Path file_name does not exist, or path is an empty string.") );
   else if( iretStat == ENOTDIR )
      throw ( std::runtime_error("A component of the path is not a directory."));
   else if( iretStat == ELOOP )
      throw ( std::runtime_error("Too many symbolic links encountered while traversing the path."));
   else if( iretStat == EACCES )
      throw ( std::runtime_error("Permission denied."));
   else if( iretStat == ENAMETOOLONG )
      throw ( std::runtime_error("File can not be read\n"));

   // Configure DOM parser.

   m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Never );
   m_ConfigFileParser->setDoNamespaces( false );
   m_ConfigFileParser->setDoSchema( false );
   m_ConfigFileParser->setLoadExternalDTD( false );

   try
   {
      m_ConfigFileParser->parse( configFile.c_str() );

      // no need to free this pointer - owned by the parent parser object
      DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();

      // Get the top-level element: NAme is "root". No attributes for "root"
      
      DOMElement* elementRoot = xmlDoc->getDocumentElement();
      if( !elementRoot ) throw(std::runtime_error( "empty XML document" ));

      // Parse XML file for tags of interest: "ApplicationSettings"
      // Look one level nested within "root". (child of root)

      DOMNodeList*      children = elementRoot->getChildNodes();
      const  XMLSize_t nodeCount = children->getLength();

      // For all nodes, children of "root" in the XML tree.

      for( XMLSize_t xx = 0; xx < nodeCount; ++xx )
      {
         DOMNode* currentNode = children->item(xx);
         if( currentNode->getNodeType() &&  // true is not NULL
             currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element 
         {
            // Found node which is an Element. Re-cast node as element
            DOMElement* currentElement
                        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            if( XMLString::equals(currentElement->getTagName(), TAG_ApplicationSettings))
            {
               // Already tested node as type element and of name "ApplicationSettings".
               // Read attributes of element "ApplicationSettings".
               const XMLCh* xmlch_OptionA
                     = currentElement->getAttribute(ATTR_OptionA);
               m_OptionA = XMLString::transcode(xmlch_OptionA);

               const XMLCh* xmlch_OptionB
                     = currentElement->getAttribute(ATTR_OptionB);
               m_OptionB = XMLString::transcode(xmlch_OptionB);

               break;  // Data found. No need to look at other elements in tree.
            }
         }
      }
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );
      ostringstream errBuf;
      errBuf << "Error parsing file: " << message << flush;
      XMLString::release( &message );
   }
}

#ifdef MAIN_TEST
/* This main is provided for unit test of the class. */

int main()
{
   string configFile="sample.xml"; // stat file. Get ambigious segfault otherwise.

   GetConfig appConfig;

   appConfig.readConfigFile(configFile);

   cout << "Application option A="  << appConfig.getOptionA()  << endl;
   cout << "Application option B="  << appConfig.getOptionB()  << endl;

   return 0;
}
#endif


 // Initialize the XML4C2 system.
   try
   {
       XMLPlatformUtils::Initialize();
   }

   catch(const XMLException& toCatch)
   {
       char *pMsg = XMLString::transcode(toCatch.getMessage());
       XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
            << "  Exception message:"
            << pMsg;
       XMLString::release(&pMsg);
       return 1;
   }

1.  XML 생성하기  

DOMImplementation* impl =
  DOMImplementationRegistry::getDOMImplementation(X("Core"));

//(Root )노드 생성 
DOMDocument* doc = impl->createDocument(
         0,                    // root element namespace URI.
         X(”company”),   // root element name
         0);                   // document type object (DTD).

DOMElement* rootElem = doc->getDocumentElement();  

// node 생성와 값에 대한 값을 넣는다.
// 노드 생성
DOMElement*  prodElem = doc->createElement(X(”product”));
rootElem->appendChild(prodElem);

// 그 노드에 맞는 값
DOMText*    prodDataVal = doc->createTextNode(X(”Xerces-C”));
          prodElem->appendChild(prodDataVal);

2. 생성한 XML 파일로 저장하기.  

static XMLCh*  gOutputEncoding = 0;

DOMWriter  *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();

// set user specified output encoding
theSerializer->setEncoding(gOutputEncoding);
XMLFormatTarget *myFormTarget;

myFormTarget = new LocalFileFormatTarget(”c://output.xml”);

theSerializer->writeNode(myFormTarget, *doc);  
3. 이미 생성된 XML 파일 검색하기  

// 이미 기본 설정한거라 보고…다운받으면 그 안에 소스가 존재합니다. 참고 바람.
// 외부 파일을 가져온다.
parser->resetDocumentPool();
doc = parser->parseURI(xmlFile);

// 파일을 검색할때는 재귀가 기본이다.

// DOMNode *n

if (n->getNodeType() == DOMNode::ELEMENT_NODE)

{

    // 노드의 이름 가져온다.
    char *name =  XMLString::transcode(n->getNodeName());

    // 노드에 대한 값을 가져온다.
    char* nodeValue = XMLString::transcode (n->getFirstChild()->getNodeValue ());

    // 속성
   if(n->hasAttributes()) {

        DOMNamedNodeMap *pAttributes = n->getAttributes();
        int nSize = pAttributes->getLength();

        // 한 노드에 붙어있는 모든 속성과 값을 가져온다.
        for(int i=0; nSize>i; i++){  
                   DOMAttr *pAttributeNode = (DOMAttr*) pAttributes->item(i);
                   // get attribute name
                   char *name = XMLString::transcode(pAttributeNode->getName());
                  
                   XERCES_STD_QUALIFIER cout << "Attribute Name : " << name << " -> “;
                   XMLString::release(&name);
                  
                   // get attribute type
                   name = XMLString::transcode(pAttributeNode->getValue());
                   XERCES_STD_QUALIFIER cout << “Attribute Value : “<< name << XERCES_STD_QUALIFIER endl;
                   XMLString::release(&name);
               }
   }
}



[출처 : http://www.soulfree.net/126]

+ Recent posts