· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
kkt49/Xerces

NoSmoke:DeleteMe kkt49

Xerces

basic function

///////////////////////////////////////
//
// - Find Node
// - Save Node (XML File)
// - (Get, Set) NodeValue, Attribute
//
///////////////////////////////////////

#ifndef __XMLFUNC_HPP
#define __XMLFUNC_HPP

#define ENC_ISO8859_1 "ISO8859-1"

//dom
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMNodeFilter.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>

#include <xercesc/util/Base64.hpp>

#include <stdio.h>
#include <unistd.h>

#include <vector>
#include <string>
#include <assert.h>

#include <iostream>
#include <fstream>

#include "FilePath.hpp"

#include "DOMTreeErrorReporter.hpp"
#include "DOMPrintFilter.hpp"
#include "DOMPrintErrorHandler.hpp"

XERCES_CPP_NAMESPACE_USE

/////////////////////////////////
// Class
//
// XMLFunc
//
// - Common XML Function
/////////////////////////////////
class XMLFunc
{
public:
    XMLFunc ();
    ~XMLFunc ();
    DOMNode * getNode (DOMNode * node, const char * node_name);
    DOMNode * getNode (DOMNode * node, const char * node_name, const char * att_name, const char * att_value);
    DOMNode * getNodeOfAttr (DOMNode *node, const char * att_name);

    
    DOMNodeList * getNodeList (DOMNode * node);
    DOMNodeList * getNodeList (DOMNode * node, const char * node_name);
    vector <DOMNode *> getNodeList (DOMNode * node, const char * node_name, const char * att_name, const char * att_value);

    string getNodeValue (DOMNode * node);
    string getNodeName  (DOMNode * node);
    bool setNodeValue (DOMNode * node, const char * node_value);
    string getNodeXML (DOMNode * node);

    DOMNode * addNode (DOMNode * node, const char * node_name);
    DOMNode * addNode (DOMNode * node, const char * node_name, const char * node_value);
    DOMNode * addNodeOfAttr (DOMNode * node, const char * node_name);
    DOMNode * addComment (DOMNode * node, const char * comment);

    // Base64 encoding & decoding
    string BinToBase64 (string & data);
    string Base64ToBin (string & data);

    // extended function (using FilePath class)
    int saveDOM (DOMNode * node, const char * filename);
};

XMLFunc::XMLFunc ()
{
}

XMLFunc::~XMLFunc ()
{
}

/////////////////////////////////
//
// XMLFunc Member Function
//
/////////////////////////////////
//노드명 검색 (발견된 첫번째 노드)
DOMNode * XMLFunc::getNode (DOMNode * node, const char * node_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    //---------------------------------------//
    XMLCh * tag_name = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);

    DOMNode * ret_node = NULL;
    //ret_node = node_list->item (0);
    for (int i = 0; i < node_list->getLength(); i++)
    {
        ret_node = node_list->item (i);
        if (ret_node->getParentNode () != cur_node)
        {
            ret_node = NULL;
            continue;
        }
        break;
    }
    //---------------------------------------//

    if (ret_node == NULL)
    {
        cout << node_name << ": getNode() err: 발견되지 않음" << endl;
        return NULL;
    }
    return ret_node;

}

//attribute 검색
DOMNode * XMLFunc::getNode (DOMNode * node, const char * node_name, const char * att_name, const char * att_value)
{
    //DOMNode * cur_node = node;
    if (!node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tagName = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)node)->getElementsByTagName (tagName);
    XMLString::release (&tagName);

    XMLCh * attValue = XMLString::transcode (att_value);
    DOMNode * ret_node = NULL;

    XMLCh attName [100];

    for (int i = 0; i < node_list->getLength(); i++)
    {
        DOMNode * cur_node = node_list->item (i);
        if (cur_node->getParentNode () != node)
            continue;

        XMLString::transcode (att_name, attName, 99);
        const XMLCh * attValue2 = ((DOMElement *)cur_node)->getAttribute (attName);
        if (XMLString::compareString (attValue, attValue2) == 0)
        {
            ret_node = ((DOMElement *)cur_node)->getAttributeNode (attName);
            XMLString::release (&attValue);
            return ret_node;
        }

    }
    XMLString::release (&attValue);

    if (ret_node == NULL)
    {
        cout << node_name << ": getNode() err: 발견되지 않음" << endl;
    }
    return ret_node;

}

DOMNode * XMLFunc::getNodeOfAttr (DOMNode *node, const char * att_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeOfAttr() err: NULL node" << endl;
        assert (cur_node);
    }
    DOMNamedNodeMap * atts = cur_node->getAttributes ();
    DOMNode * attNode = NULL;
    for (int i = 0; i < atts->getLength(); i++)
    {
        attNode = atts->item (i);
        char * attName = XMLString::transcode (attNode->getNodeName ());
        if (strcmp (attName, att_name) == 0)
        {
            XMLString::release (&attName);
            return attNode;
        }
        XMLString::release (&attName);
    }
    cout << att_name << ": getNodeOfAttr() err: 발견되지 않음" << endl;
    return NULL;
}

string XMLFunc::getNodeValue (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    char * node_value;
    string value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {
        if (!cur_node->hasChildNodes())
        {
            value = "";
        }
        else
        {
            node_value = XMLString::transcode (cur_node->getFirstChild()->getNodeValue ());
            value = node_value;
            XMLString::release (&node_value);
        }
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_value = XMLString::transcode (cur_node->getNodeValue ());
        value = node_value;
        XMLString::release (&node_value);
    }
    else
    {
        cout << "getNodeValue() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
    }
    return value;
}

string XMLFunc::getNodeName  (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    char * node_name;
    string value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {
        node_name = XMLString::transcode (cur_node->getNodeName ());
        value = node_name;
        XMLString::release (&node_name);
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_name = XMLString::transcode (cur_node->getNodeName ());
        value = node_name;
        XMLString::release (&node_name);
    }
    else
    {
        cout << "getNodeName() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
    }
    return value;
}

bool XMLFunc::setNodeValue (DOMNode * node, const char * value)
{

    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeValue() err: NULL node" << endl;
        assert (cur_node);
    }

    XMLCh * node_value;
    if (cur_node->getNodeType () == DOMNode::ELEMENT_NODE)
    {

        node_value = XMLString::transcode (value);
        if (!cur_node->hasChildNodes()) // append node
        {
            DOMText * textNode = (cur_node->getOwnerDocument())->createTextNode (node_value);
            ((DOMElement *)cur_node)->appendChild (textNode);
        }
        else //modify node
        {
            cur_node->getFirstChild()->setNodeValue (node_value);
        }
        XMLString::release (&node_value);
    }
    else if (cur_node->getNodeType () == DOMNode::ATTRIBUTE_NODE)
    {
        node_value = XMLString::transcode (value);
        cur_node->setNodeValue (node_value);
        XMLString::release (&node_value);
    }
    else
    {
        cout << "setNodeValue() err: NodeType is not (ELEMENT or ATTRIBUTE)" << endl;
        return false;
    }
    return true;
}

DOMNodeList *
XMLFunc::getNodeList (DOMNode * node, const char * node_name)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return NULL;
    }

    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tag_name = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);
    return node_list;
}

vector <DOMNode *> XMLFunc::getNodeList (DOMNode * node, const char * node_name, const char * att_name, const char * att_value)
{
    vector <DOMNode *> vect_node_list;
    if (!node)
    {
        cout << "getNode() err" << endl;
        cout << " : node = NULL, node_name = " << node_name << endl;
        return vect_node_list;
    }

    if (node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return vect_node_list;
    }

    XMLCh * tagName = XMLString::transcode (node_name);
    DOMNodeList * node_list = ((DOMElement *)node)->getElementsByTagName (tagName);
    XMLString::release (&tagName);

    XMLCh * attValue = XMLString::transcode (att_value);

    XMLCh attName [100];

    for (int i = 0; i < node_list->getLength(); i++)
    {
        DOMNode *cur_node = node_list->item (i);
        if (cur_node->getParentNode () != node)
            continue;
        XMLString::transcode (att_name, attName, 99);
        const XMLCh * attValue2 = ((DOMElement *)cur_node)->getAttribute (attName);
        if (XMLString::compareString (attValue, attValue2) == 0)
        {
            vect_node_list.push_back (cur_node);
        }

    }
    XMLString::release (&attValue);
    return vect_node_list;
}

DOMNodeList *
XMLFunc::getNodeList (DOMNode * node)
{
    DOMNode * cur_node = node;
    if (!cur_node)
    {
        cout << "getNodeList() err" << endl;
        cout << " : node = NULL" << endl;
        return NULL;
    }
    if (cur_node->getNodeType () != DOMNode::ELEMENT_NODE)
    {
        cout << "getNode() err: ELEMENT_NODE 가아님" << endl;
        return NULL;
    }

    XMLCh * tag_name = XMLString::transcode ("*");
    DOMNodeList * node_list = ((DOMElement *)cur_node)->getElementsByTagName (tag_name);
    XMLString::release (&tag_name);
    return node_list;
}

string XMLFunc::getNodeXML (DOMNode * node)
{
    XMLCh tempStr[100];
    XMLString::transcode ("LS", tempStr, 99);
    DOMImplementation * impl = DOMImplementationRegistry::getDOMImplementation (tempStr);

    DOMWriter * writer = ((DOMImplementationLS*)impl)->createDOMWriter();
    XMLCh * pretty_format = XMLString::transcode ("format-pretty-print");
    writer->setFeature (pretty_format, true);
    XMLString::release (&pretty_format);

    MemBufFormatTarget * formTarget = new MemBufFormatTarget ();
    writer->writeNode (formTarget, *node);
    string xml = (const char *)formTarget->getRawBuffer();

    //formTarget->reset();
    delete formTarget;
    writer->release ();
    return xml;
}

int XMLFunc::saveDOM (DOMNode * node, const char * filename)
{
    FilePath file;
    string xml = getNodeXML (node);
    file.SaveFile (filename, xml.c_str(), xml.size(), 0755);
    return 0;
}

DOMNode * XMLFunc::addNode (DOMNode * node, const char * node_name, const char * node_value)
{

    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMElement * e = (node->getOwnerDocument())->createElement (tempStr);
    DOMNode * add_node = node->appendChild (e);
    setNodeValue (add_node, node_value);
    
    return add_node;
}

DOMNode * XMLFunc::addNode (DOMNode * node, const char * node_name)
{

    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMElement * e = (node->getOwnerDocument())->createElement (tempStr);
    DOMNode * add_node = node->appendChild (e);
    
    return add_node;
}

DOMNode * XMLFunc::addNodeOfAttr (DOMNode * node, const char * node_name)
{
    XMLCh tempStr[100];
    XMLString::transcode (node_name, tempStr, 99);
    DOMAttr * e = node->getOwnerDocument()->createAttribute (tempStr);
    ((DOMElement *)node)->setAttributeNode (e);
    DOMNode * ret_attr = getNodeOfAttr (node, node_name);
    return ret_attr;
}

DOMNode * XMLFunc::addComment (DOMNode * node, const char * comment)
{
    XMLCh * tempStr = XMLString::transcode (comment);
    DOMComment * e = node->getOwnerDocument()->createComment (tempStr);
    DOMNode * add_node = node->appendChild (e);
    XMLString::release (&tempStr);
    return add_node;
}

string XMLFunc::BinToBase64 (string & data)
{
    unsigned int length_en;
    char * img = (char *)Base64::encode ((XMLByte *)data.c_str(), data.size(), &length_en, 0);
    string base64 = img;
    XMLString::release (&img);
    return base64;
}

string XMLFunc::Base64ToBin (string & data)
{
    unsigned int len_out = 0;
    XMLByte * de_img = Base64::decode ((unsigned char *)data.c_str(), &len_out, 0);
    string bin = string ((char *)de_img, len_out);
    XMLString::release (&de_img);
    return bin;
}

#endif

Dom Parsing

#ifndef __XMLTRANS_HPP
#define __XMLTRANS_HPP

#include "XMLFunc.hpp"

/////////////////////////////////
// Class
//
// XMLTrans
//
// - Parsing XML
// - Make XML
/////////////////////////////////
class XMLTrans : public XMLFunc
{
private:
    MemBufInputSource * memBufIS;
    XercesDOMParser * parser;
    DOMImplementation * impl;
    DOMDocument * doc;
public:
    DOMNode * root;
    static int MemBufId;
    int err_count;

private:
    bool Parse (string & xml); // LoadXML ()

public:
    XMLTrans (); // 생성자
    virtual ~XMLTrans (); // 소멸자

    bool LoadXML (string & );
    DOMNode * createRoot (const char * root_name);
    // etc.

}; //class XMLTrans

//////////////////////////////////////
// XMLTrnas Static Member
int XMLTrans::MemBufId = 0;    //static
//////////////////////////////////////


/////////////////////////////////
//
// XMLTrans Member Function
//
/////////////////////////////////

XMLTrans::XMLTrans () //생성자
{
    memBufIS = NULL;
    parser = NULL;
    doc = NULL;
    root = NULL;
}

XMLTrans::~XMLTrans () //소멸자
{
    if (parser != NULL)
    {
        delete parser;
        //cout << "parser 객체 소멸" << endl;
        if (memBufIS != NULL)
        {
            delete memBufIS;
            //cout << "memBufIS 객체 소멸" << endl;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
        //cout << "doc release() 소멸" << endl;
    }

}

//////////////////////////////////////////////////////
bool XMLTrans::Parse (string & xml)
{
    parser = new XercesDOMParser;

    char chId[10];
    sprintf (chId, "%d", MemBufId);
    
    memBufIS = new MemBufInputSource
    (
        (const XMLByte*)(xml).c_str()
        , (xml).size()
        , chId
        , false
    );

    ///////////////////////////
    //encoding 을 무조건 ISO8859-1로 바꿔준다.
    ///////////////////////////
    //XMLCh * enc = XMLString::transcode (ENC_ISO8859_1);
    XMLCh * enc = XMLString::transcode ("ISO8859-1");
    memBufIS->setEncoding (enc);
    XMLString::release (&enc);
    //parser->setDoSchema (XercesDOMParser::Val_Auto);
    //parser->setDoSchema (XercesDOMParser::Val_Always);
    //parser->setDoNamespaces (true);

    bool errorsOccured = false;
    try
    {
        ///////////////////////////
        // Parse
        ///////////////////////////
        parser->parse (*memBufIS);
    }
    catch (const XMLException& e)
    {
        cerr << "An err occurred during parsing\n Message: "
            << StrX (e.getMessage ()) << endl;
        errorsOccured = true;
        return false;
    }
    catch (const DOMException& e)
    {
        const unsigned int maxChars = 2047;
        XMLCh errText [maxChars + 1];

        cerr << "\nDOM Error during parsing \n"
            << "DOMException code is: " << e.code << endl;
        if (DOMImplementation::loadDOMExceptionMsg (e.code, errText, maxChars))
            cerr << "Message is: " << StrX (errText) << endl;
        errorsOccured = true;
        return false;
    }
    catch (...)
    {
        cerr << "An error occurred during parsing\n" << endl;
        errorsOccured = true;
        return false;
    }
    // non-wellformed XML
    err_count = parser->getErrorCount ();

    ///////////////////////////
    // DOMDocument
    ///////////////////////////
    doc = parser->getDocument ();
    root = doc->getDocumentElement ();
    return true;
}

bool XMLTrans::LoadXML (string & xml)
{
    if (parser != NULL)
    {
        delete parser;
        if (memBufIS != NULL)
        {
            delete memBufIS;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
        //cout << "load xml release doc" << endl;
    }

    memBufIS = NULL;
    parser = NULL;
    doc = NULL;
    root = NULL;
    XMLPlatformUtils::atomicIncrement (MemBufId);

    if (!Parse (xml))
    {
        cout << "parse err" << endl;
        return false;
    }

    return true;
}

DOMNode * XMLTrans::createRoot (const char * root_name)
{
    if (parser != NULL)
    {
        delete parser;
        if (memBufIS != NULL)
        {
            delete memBufIS;
        }
    }
    else if (doc != NULL)
    {
        doc->release ();
        doc = NULL;
    }

    XMLCh tempStr[100];
    XMLString::transcode ("LS", tempStr, 99);
    impl = DOMImplementationRegistry::getDOMImplementation (tempStr);

    XMLString::transcode (root_name, tempStr, 99);
    doc = impl->createDocument (0, tempStr, 0);

    //XMLCh * enc = XMLString::transcode (ENC_ISO8859_1);
    XMLCh * enc = XMLString::transcode ("ISO8859-1");
    doc->setEncoding (enc);
    XMLString::release (&enc);

    root = doc->getDocumentElement ();

    return root;
}

#endif




sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2003-09-23 00:05:04
Processing time 0.0121 sec