⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhang.txt

📁 用C++编的小程序。
💻 TXT
字号:
A C++ Template Wrapper for the XML SAX API
by Yingjun Zhang 


Figure 1:
<BookedOrders xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
    <CustomerOrder>
        <OrderID>1000</OrderID>
        <Customer>XYZ Inc.</Customer>
        <Item>Steel</Item>
        <Unit>Ton</Unit>
        <Quantity>2.8</Quantity>
    </CustomerOrder>
    <CustomerOrder>
        <OrderID>1001</OrderID>
        <Customer>ABC Inc.</Customer>
        <Item>Plastic</Item>
        <Unit>Roll</Unit>
        <Quantity>30.5</Quantity>
    </CustomerOrder>
</BookedOrders>

     


Listing 1:

// ...
class CustomerOrderHandler : public ISAXContentHandler  
{
private:
    int         m_OrderID;
    wchar_t     m_CustomerName[20];
    wchar_t     m_ItemName[20];
    wchar_t     m_Unit[20];    
    double      m_Quantity;
    XmlString   m_CurrentTag;
public:
    CustomerOrderHandler(){}
    virtual ~CustomerOrderHandler(){}
    // other member functions not shown
    virtual HRESULT STDMETHODCALLTYPE startElement( 
        /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ wchar_t __RPC_FAR *pwchRawName,
        /* [in] */ int cchRawName,
        /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
    {
        // record where the document is being parsed
        m_CurrentTag = XmlString(pwchLocalName, cchLocalName);
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE endElement( 
        /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ wchar_t __RPC_FAR *pwchRawName,
        /* [in] */ int cchRawName)
    {
        m_CurrentTag = XmlString(pwchLocalName, cchLocalName);
        if (m_CurrentTag == L"CustomerOrder")  // whole order has been parsed,
        {                                      // process this order now.
            std::wcout << L"Order " << m_OrderID 
            << L" from " << m_CustomerName 
            << L": " << m_ItemName 
            << L" " << m_Quantity 
            << L" " << m_Unit 
            << L"s has been processed." << std::endl;
        }
        m_CurrentTag = L"";  // clear the status for next element
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE characters( 
        /* [in] */ wchar_t __RPC_FAR *pwchChars,
        /* [in] */ int cchChars)
    {
        if (m_CurrentTag == L"OrderID")
            m_OrderID = xmlstring_cast<int>(XmlString(pwchChars, cchChars));
        else if (m_CurrentTag == L"Customer")
        {
             wcsncpy(m_CustomerName, pwchChars, cchChars);
             m_CustomerName[cchChars] = L'\0';
        }
        else if (m_CurrentTag == L"Item")
        {
            wcsncpy(m_ItemName, pwchChars, cchChars);
            m_ItemName[cchChars] = L'\0';
        }
        else if (m_CurrentTag == L"Unit")
        {
            wcsncpy(m_Unit, pwchChars, cchChars);
            m_Unit[cchChars] = L'\0';
        }
        else if (m_CurrentTag == L"Quantity")
          m_Quantity = xmlstring_cast<double>(XmlString(pwchChars, cchChars));
         return S_OK;
    }
};
#endif 


Listing 2:

//.....
template <class Data, class Functor>
class DocumentContentHandler : public BaseContentHandler
{ 
protected:
    typedef DocumentContentHandler<Data, Functor>  DocHandlerType;
    typedef map<XmlString, BaseContentHandler*>    ContentHandlerMap;
    typedef ContentHandlerMap::iterator    ContentHandlerIterator;
protected:
    ContentHandlerMap                         m_AllHandlers;
    stack<BaseContentHandler*>                m_ActiveHandlers;
    ISAXXMLReader*                            m_pXMLReader;
public:
    // destructor and other functions not shown
    DocumentContentHandler(const XmlString& strDocumentName,
                            Functor* pFunctor) 
        : BaseContentHandler(strDocumentName) 
    {
        m_AllHandlers.insert(
          ContentHandlerMap::value_type(strDocumentName,this));
          CompositeContentHandler<Data, Functor>*    pHandler = 
                 new DataHandler(Data::GetClassName(),this,pFunctor);
    }
    virtual HRESULT STDMETHODCALLTYPE startElement( 
        /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ wchar_t __RPC_FAR *pwchRawName,
        /* [in] */ int cchRawName,
        /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
    {
        ContentHandlerIterator iter = 
            m_AllHandlers.find(XmlString(pwchLocalName));
        if (iter != m_AllHandlers.end())
        {
            m_ActiveHandlers.push(iter->second);
            m_pXMLReader->putContentHandler(iter->second);
        }
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE endElement( 
        /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
        /* [in] */ int cchNamespaceUri,
        /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
        /* [in] */ int cchLocalName,
        /* [in] */ wchar_t __RPC_FAR *pwchRawName,
        /* [in] */ int cchRawName)
    {
        if(!m_ActiveHandlers.empty())
            m_ActiveHandlers.pop();
        if(!m_ActiveHandlers.empty())
            m_pXMLReader->putContentHandler(
                m_ActiveHandlers.top());
        return S_OK;
    }
};

Listing 3:

// only partial listing
template <class Data, class Functor>
class CompositeContentHandler : public BaseContentHandler  
{
    BaseContentHandler*         m_pDocumentHandler;
    Functor*                    m_pFunctor;    
    Data                        m_Data;
    vector<ContentHandlerPtr>   m_ChildHandlers;    
public:
     CompositeContentHandler(const XmlString& name,
          BaseContentHandler* pDocumentHandler, Functor*    pFunctor) 
        : BaseContentHandler(name), m_pDocumentHandler(pDocumentHandler),
                                    m_pFunctor(pFunctor)
    {
        BaseContentHandler* pTempHandler;
        const XmlBindingEntry* pEntry =  m_Data.GetXmlBindingEntries();
        while(pEntry->eDataType != eXML_EMPTY) 
        {
          pTempHandler = CreateHandler(pDocumentHandler, pEntry);
          m_ChildHandlers.push_back(pTempHandler);
          m_pDocumentHandler->AddContentHandler(pTempHandler);
          ++pEntry;
        }
        m_pDocumentHandler->AddContentHandler(this);
    }
    virtual HRESULT STDMETHODCALLTYPE endElement( 
            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ wchar_t __RPC_FAR *pwchRawName,
            /* [in] */ int cchRawName)
    {
         CopyTo(&m_Data);
        (*m_pFunctor)(m_Data); 
        return m_pDocumentHandler->endElement(
            pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName,
            pwchRawName, cchRawName);    
    }
    virtual void CopyTo(void* dest)
    {
        ClassContentHandlers::iterator iter, iterEnd;
        iter=m_ChildHandlers.begin();
        iterEnd = m_ChildHandlers.end();
        for(;iter!= iterEnd; ++iter)
            (*iter)->CopyTo(dest);
    }
};


Listing 4:

#if !defined(CUSTOMERORDER__H)
#define      CUSTOMERORDER__H
#include "XmlBinding.h"
#include <iostream>
using std::wostream;
class CustomerOrder
{
BEGIN_XML_BINDING(L"CustomerOrder", CustomerOrder)
    XML_ELEMENT(L"OrderID", eXML_INT, m_OrderID)
    XML_ELEMENT(L"Customer", eXML_STRING, m_CustomerName)       
    XML_ELEMENT(L"Item", eXML_STRING, m_ItemName)       
    XML_ELEMENT(L"Unit", eXML_STRING, m_Unit)       
    XML_ELEMENT(L"Quantity", eXML_DOUBLE, m_Quantity)
END_XML_BINDING()
    int            m_OrderID;
    wchar_t        m_CustomerName[20];
    wchar_t        m_ItemName[20];
    wchar_t        m_Unit[20];    
    double        m_Quantity;
public:
    friend wostream& operator << (wostream& wo, const CustomerOrder& order);
};
wostream& operator << (wostream& wo, const CustomerOrder& order)
{
    return wo << L"Order " << order.m_OrderID 
        << L" from " << order.m_CustomerName 
        << L": " << order.m_ItemName 
        << L" " << order.m_Quantity 
        << L" " << order.m_Unit 
        << L"s has been processed." << std::endl;
}
#endif


Listing 5:

#if !defined(CUSTOMERORDERPROCESSOR__H)
#define      CUSTOMERORDERPROCESSOR__H
#include "CustomerOrder.h"
#include <iostream>
class CustomerOrderProcessor
{
public:
    //The processings for the business order would go here.
    //For simplicity, it only prints the order out
    void operator() (const CustomerOrder& co)
    {
        std::wcout << co;
    }
};
#endif


Listing 6:

#pragma warning (disable:4786)
#include "DocumentContentHandler.h"
#include "CustomerOrderProcessor.h"
#include <iostream>
int main()
{
     typedef DocumentContentHandler<CustomerOrder, CustomerOrderProcessor> 
                                                       CustomerOrderHandler;
    ::CoInitialize(NULL);
    CustomerOrderProcessor order_processor;
    CustomerOrderHandler   order_handler(L"BookedOrders", &order_processor);
    order_handler.Setup();
    XmlString URL(L"CustomerOrder.xml");
    HRESULT hr = order_handler.Parse(URL);
    std::wcout << L"All Customer Order Processing Finished." << std::endl; 
    ::CoUninitialize();
    return 0;
}







5


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -