利用VC++实现对XML结点的更新和追加

本文详细介绍了如何根据配置文件的内容对XML文件中的节点进行更新或插入操作,包括读取配置文件、解析XML文件、定位节点并修改或新增节点等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现功能:根据配置文件(XXXX.ini)中的内容对XML中节点进行操作,如果XML中存在与配置文件中相同的节点,则根据配置文件将XML文件中相应节点的值进行更新;如果XML文件中不存在配置文件中出现的节点,则在XML中将新节点及值进行插入操作。

 

◆XML文档结构如下

//--------------------------------------------------------------------------------------------

- <printer driver-name="OKI C710(PS)">
  <color-profile path="ColorProfiles/OkiC710CMY.icc" />
  </printer>
- <printer driver-name="OKI C710(PCL)">
  <color-profile path="ColorProfiles/OkiC710CMY.icc" />
  </printer>
- <printer driver-name="OKI C830(PS)">
  <color-profile path="ColorProfiles/OkiC830CMY_new.icc " />
  </printer>
- <printer driver-name="OKI C830(PCL)">
  <color-profile path="ColorProfiles/OkiC830CMY.icc" />
  </printer>

//--------------------------------------------------------------------------------------------

 

◆配置文件结构如下

//----------------------------------------------------------------------------------------------

[Driver]
D1=OKI C830(PCL);OkiC830CMY_new;ColorProfiles/OkiC830CMY_new.icc

D2=OKI C810(PCL);OkiC810CMY_new;ColorProfiles/OkiC810CMY_new.icc

//-----------------------------------------------------------------------------------------------

 

实现步骤:

1, 读取配置文件,并将其中的信息内容用类对像进行保存

2, 对XML档进行更新.

因为整个过程并不复杂,现将代码附上。

 

类定义

//CCustomMediaInfoクラスの定義
//機能:GridLayouter機種設定ツールのGLPDFInfo.datファイル情報を初期化処理
//期日:2009.10.29
//作成:
//その他:The CustomMedia.ini file is located at ../CustomMedia/CustomMediaInfo.ini

#define MAX_UPDATE_PRN 256 //The must number of printers to be updated.

//To save the value of every item of a line in GLPDFInfo.dat or okPrnInfo.dat.
struct CM_PRN_INFO
{
    TCHAR szPrnName[MAX_PATH]; //プリンタ名を格納,例:C8800
    TCHAR szPCLName[MAX_PATH];//DriverName,PCL
    TCHAR szPSName[MAX_PATH];//DriverName ,PS
    TCHAR szHDDPath[MAX_PATH];//HDDを実装すれば、PJLPathの格納;例:C8800.pjl
    TCHAR szNOHDDPath[MAX_PATH];//HDDを実装しなければ、PJLPathの格納
   
};

class CCustomMediaInfo
{
public:
    CCustomMediaInfo(TCHAR* pCMInfoFileName);
public:
    ~CCustomMediaInfo(void);

    int GetCMFileInfo();//CustomMediaInfo.iniファイルを初期化読む

    int GetCMPrinterCount();//Get the Count of printers in customMediaInfo.ini file.

    void GetCMPrinterName(int nIndex, TCHAR* pCMPrinterName);//CustomMediaInfo.iniファイル中、プリンタ索引はnIndex時、プリンタ名を戻る。
    void GetCMPSName(int nIndex, TCHAR* pCMPSName);//CustomMediaInfo.iniファイル中、プリンタ索引はnIndex時、プリンタPS名を戻る。
    void GetCMPCLName(int nIndex, TCHAR* pCMPCLName);//CustomMediaInfo.iniファイル中、プリンタ索引はnIndex時、プリンタPCL名を戻る。
   
    void GetCMHDDPJLPath(TCHAR* pPrnName, TCHAR* pCMHDDPJLPath);//CustomMediaInfo.iniファイル中、HDD実装すれば、プリンタ名はpPrnName時、PJLファイルのFULLPathを戻る。
    void GetCMNOHDDPJLPath(TCHAR* pPrnName, TCHAR* pCMNOHDDPJLPath);//CustomMediaInfo.iniファイル中、HDD実装しなければ、プリンタ名はpPrnName時、PJLファイルのFULLPathを戻る。

    DWORD GetCMHDDPJLSize(TCHAR* pPrnName);//Get the HDD_PJL file's size.
    DWORD GetCMNOHDDPJLSize(TCHAR* pPrnName);//Get the NO_HDD PJL file's size
private:
    TCHAR* m_pCMInfoFileName;//初期化時、CustomMediaInfo.Iniファイル名を格納、パスを含まれない。
    int m_iCMPrnCount;//Iniファイル中、プリンタ数量を格納
    CM_PRN_INFO* m_pCMPrnInfo;//Iniファイルで読んだプリンタとPJLファイル名を格納

    TCHAR* m_pCMFolderPath;//The path of customMediaInfo.ini file's folder.

};

 

//****************************************************************************//
//機能:XMLファイルに更新と追加操作を実行する。
//戻る:0  成功
//      1 GridLayouter存在しない
//   2 XMLファイル操作失敗 
//入力:なし
//出力:なし
//****************************************************************************//

#import <msxml2.dll>//导入XML库

int CGLUpdateInfo::UpdateXMLFile()
{
    //変数定義
    //For XML Path

    HKEY    hkLocal; //handel to register
    LONG    lResult;
    TCHAR    RegRoot[MAX_PATH];//save the register table path of GridLayouter
    DWORD    dwType, dwSize;
    TCHAR    szAppPath[MAX_PATH];//save the return value of GridLayouter's Path

    //For XML file
    MSXML2::IXMLDOMDocumentPtr pXMLDoC; //pointer to the XML document
    MSXML2::IXMLDOMNodeListPtr pPrinterList, pColorProfileList;//Pointer to printerList and colorProfile list at XML file.
    MSXML2::IXMLDOMNamedNodeMapPtr pNodesAttrs, pSubNodesAttrs;//Colection for Nodes,typically used for attributes.
    MSXML2::IXMLDOMNodePtr pSelectPrinterNode, pSelectColorProfileNode;//pointer to current select node.
    MSXML2::IXMLDOMNodePtr pAttrDriverNameNode;// attribute dirver-name
    MSXML2::IXMLDOMNodePtr pAttrColorProfilePathNode;// path of color-profile

    MSXML2::IXMLDOMNodePtr pRootNode, pSecondRootNode; //used for adding item
    MSXML2::IXMLDOMElementPtr pElementChild, pElementChild2;//used for adding item.

    CComBSTR driverNameText; //text of driver-name
    CComBSTR colorProfilePathText;// text of color-profile

    //First: Search the Register to confirm GridLayouter is installed or not

    ZeroMemory(RegRoot,MAX_PATH);
    _stprintf_s(RegRoot,_countof(RegRoot),_T("%s"),_T("SOFTWARE//Classes//GridLayouter.Document//shell//open//command"));
    if(lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegRoot,0, KEY_READ,&hkLocal) !=ERROR_SUCCESS)
    {
        return 1;   
    }

    dwSize = sizeof(szAppPath);
    dwType = REG_SZ; //String end with zero.
    if(RegQueryValueEx(hkLocal,(LPCTSTR)_T(""), NULL,&dwType,(LPBYTE)szAppPath,&dwSize)!=ERROR_SUCCESS) //Get the default value
    {
        return 1;
    }
    //Second Get the path of GOSettings.xml →m_pDestXMLPath
    TCHAR szXMLName[MAX_PATH];
    ZeroMemory(szXMLName, MAX_PATH);

    *(_tcsrchr(szAppPath,_T('//'))) = NULL;
    CString strAppPath(szAppPath);
    int i_sPath = strAppPath.Find(_T('"'));//delete the first character,because it is a quato(")
    strAppPath = strAppPath.Right(strAppPath.GetLength() - i_sPath -1);
    lstrcpy(szXMLName, strAppPath.GetBuffer());

    _stprintf_s(m_pDestICCFolder,MAX_PATH,_T("%s//ColorProfiles"),szXMLName); //Save the path of ColorProfiles Folder.


    lstrcat(szXMLName,_T("//GOSettings.xml"));//

    //m_pDestXMLPath = szXMLName; //Save the XML Path
    lstrcpy(m_pDestXMLPath, szXMLName);

    //Third Open the XML file and update it
    long nListPrinterNodeLen;//length of printer node list.
    HRESULT hr;
    variant_t vResult;//save return value;

    hr = CoInitialize(NULL);//Initializes the COM library
    if(S_OK != hr)
    {
        return 2;   
    }
    hr = pXMLDoC.CreateInstance(__uuidof(MSXML2::DOMDocument26));
    if(S_OK != hr)
    {
        return 2;   
    }
    vResult = pXMLDoC->load(m_pDestXMLPath);//Load XML File
    if (!(bool)vResult)
    {
        return 2;//load xml failed.
    }
   
    //Get the node list
    pPrinterList = pXMLDoC->getElementsByTagName(_T("printer"));//get the tag of <printer></printer>
    if (!pPrinterList)
    {
        return 2;
    }

    hr = pPrinterList->get_length(&nListPrinterNodeLen);//get the length of nodelist
    if(S_OK != hr)
    {
        return 2;   
    }

    //travers the sturcuter GL_PRN_INFO,according to the printer name to update XML file
    for (int iCount = 1; iCount<= m_iGLUPPrnCount; iCount++)
    {
        //Traverse the printer nodelist
        for (int iNode = 0; iNode < nListPrinterNodeLen; iNode++)
        {
            //get current node
            hr = pPrinterList->get_item(iNode, &pSelectPrinterNode);
            if (S_OK != hr)
            {
                return 2;
            }

            //Get the attribute of node
            pSelectPrinterNode->get_attributes(&pNodesAttrs);
            pAttrDriverNameNode = pNodesAttrs->getNamedItem(_T("driver-name"));           
            hr = pAttrDriverNameNode ->get_text(&driverNameText);
            if (S_OK != hr)
            {
                return 2;
            }

            //プリンタ名はXMLに存在の場合は、更新実行する。
            //プリンタ名はXMLファイルに存在しないの場合は、追加する。
            if (lstrcmp(_com_util::ConvertBSTRToString(driverNameText.m_str),m_pGLUPPrnInfo[iCount].sPrinterName) == 0)
            {
                //Next,Traverse the subNodelist(<color-profile path=....>)
                //Get the path of icc file
                hr = pSelectPrinterNode->get_childNodes(&pColorProfileList);
                if (S_OK != hr)
                {
                    return 2;
                }
                //get the length of subNodelist
                long nSubListLen;
                hr =  pColorProfileList->get_length(&nSubListLen);
                if(nSubListLen == 1)
                {
                    //get current node item
                    hr = pColorProfileList->get_item(0, &pSelectColorProfileNode);
                    if (S_OK!= hr)
                    {
                        return 2;
                    }
                    //get its attributes
                    pSelectColorProfileNode->get_attributes(&pSubNodesAttrs);
                    pAttrColorProfilePathNode = pSubNodesAttrs->getNamedItem(_T("path"));
                    //EXECUTE:update the path of XML file
                    hr = pAttrColorProfilePathNode->put_text(_com_util::ConvertStringToBSTR(m_pGLUPPrnInfo[iCount].sICCPath));
                    if (S_OK != hr)
                    {
                        return 2;
                    }
                    //保存
                    hr = pXMLDoC->save(m_pDestXMLPath);//save the XML
                    if (S_OK != hr)
                    {
                        return 2;
                    }
                    break;
                }//if(nSubListLen == 1)
               
            }//if (driverNameText == m_pGLUPPrnInfo[iCount].sPrinterName)
            else //driverNameText != m_pGLUPPrnInfo[iCount].sPrinterName)
            {
                //XMLファイルにNodeを追加
                if(iNode == nListPrinterNodeLen -1)
                {
                    pRootNode = pXMLDoC->selectSingleNode(_T("gridonput-config"));
                    if (!pRootNode)
                    {
                        return 2;
                    }
                    pSecondRootNode = pRootNode->selectSingleNode(_T("directprint-settings"));
                    if (!pSecondRootNode)
                    {
                        return 2;
                    }
                    pElementChild = pXMLDoC->createElement((_bstr_t)(char*)(_T("printer")));
                    pElementChild->setAttribute((_bstr_t)(char*)_T("driver-name"), m_pGLUPPrnInfo[iCount].sPrinterName);
                    pSecondRootNode->appendChild(pElementChild);//append the <printer driver-name >

                    //create the node color-profile path
                    pElementChild2 = pXMLDoC->createElement((_bstr_t)(char*)_T("color-profile"));
                    pElementChild2->setAttribute((_bstr_t)(char*)_T("path"), m_pGLUPPrnInfo[iCount].sICCPath);
                    pElementChild->appendChild(pElementChild2);//append the <color-profile path>

                    pXMLDoC->save(m_pDestXMLPath);//save the results.
                    break;                   
                }
           
            }//end if

        }//for(int iNode;.........)
    }//for(int iCount........)
    //CoUninitialize();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值