利用VC++实现对XML结点的更新和追加
2010-04-15 13:30
393 查看
实现功能:根据配置文件(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;
}
◆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;
}
相关文章推荐
- 利用ASP和XML实现客户端多表单域数据动态更新
- 利用VC++实现AVI文件的合成和分解
- java网络编程--解析通过web.xml文件控制利用过滤器实现编码格式步骤
- 利用反射检查程序集实现自动更新
- 利用VC++与MSXML解析XML文档
- 利用MSXML解析XML文本(VC)
- 利用XML实现通用WEB报表打印(5)
- 利用VC++实现AVI文件的合成和分解(Bmp图片)
- 孙鑫VC学习笔记:第十六讲 利用关键代码段实现线程间的同步
- MSSQL数据同步利用数据库复制技术实现数据同步更新
- 利用数据库复制技术实现数据同步更新(SQL SERVER)
- 利用VC++实现AVI文件的合成和分解
- [XML] 利用XML串行化,实现应用程序配置类的存储和读取
- 利用SAX、DOM和Pull实现对schools.xml的解析并进行单元测试
- 利用 T-sql 的从句 for xml path('') 实现多行合并到一行, 并带有分隔符
- asp.net2.0 中最快方式实现gridview 更新 删除 xml文件
- VC++中利用MSXML解析XML文档
- 利用fatfs文件系统实现了SD卡追加…
- 原生态Ajax写法异步提交,巧妙利用innerHTML实现不清空原来内容追加请求结果
- ibatis 批量插入,批量更新,批量删除,xml与Java代码实现方式