讓Expat支援中文XML

來源:互聯網
上載者:User

在很多地方看到對一篇<如何讓Expat支援中文XML>的文章,其中提到:

Expat並不支援中文,Expat不支援gb2312編碼格式,主要支援UTF-8編碼格式

兩種解決辦法:
    1、改寫Expat原始碼,這樣效率高,但不方便今後Expat代碼的升級;
    2、首先將gb2312格式的文本轉換為UTF-8格式文本,然後讓Expat解析,解析出的資料再轉換為gb2312格式以方便處理。效率較第一種方法低。

第二中方法,在那篇文章中有提到,但是他給的串連卻不能用,很是鬱悶.所以自己找了格式裝換的代碼如下:

在LINUX上進行編碼轉換時,既可以利用iconv函數族編程實現,也可以利用iconv命令來實現,只不過後者是針對檔案的,即將指定檔案從一種編碼轉換為另一種編碼。
利用iconv函數族進行編碼轉換
iconv函數族的標頭檔是iconv.h,使用前需包含之。
#include <iconv.h>
iconv函數族有三個函數,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
此函數說明將要進行哪兩種編碼的轉換,tocode是目標編碼,fromcode是原編碼,該函數返回一個轉換控制代碼,供以下兩個函數使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
此函數從inbuf中讀取字元,轉換後輸出到outbuf中,inbytesleft用以記錄還未轉換的字元數,outbytesleft用以記錄輸出緩衝的剩餘空間。 (3) int iconv_close(iconv_t cd);
此函數用於關閉轉換控制代碼,釋放資源。
例子1: 用C語言實現的轉換樣本程式

/* f.c : 代碼轉換樣本C程式 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安裝";
char out[OUTLEN];

//unicode碼轉為gb2312碼
rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN);
printf("unicode-->gb2312 out=%sn",out);
//gb2312碼轉為unicode碼
rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
printf("gb2312-->unicode out=%sn",out);
}
//代碼轉換:從一種編碼轉為另一種編碼
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;

cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
memset(outbuf,0,outlen);
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
//UNICODE碼轉為GB2312碼
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB2312碼轉為UNICODE碼
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}

例子2: 用C++語言實現的轉換樣本程式

/* f.cpp : 代碼轉換樣本C++程式 */
#include <iconv.h>
#include <iostream>

#define OUTLEN 255

using namespace std;

// 代碼轉換操作類
class CodeConverter {
private:
iconv_t cd;
public:
// 構造
CodeConverter(const char *from_charset,const char *to_charset) {
cd = iconv_open(to_charset,from_charset);
}

// 析構
~CodeConverter() {
iconv_close(cd);
}

// 轉換輸出
int convert(char *inbuf,int inlen,char *outbuf,int outlen) {
char **pin = &inbuf;
char **pout = &outbuf;

memset(outbuf,0,outlen);
return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}
};

int main(int argc, char **argv)
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安裝";
char out[OUTLEN];

// utf-8-->gb2312
CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;

// gb2312-->utf-8
CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}

以上是在LINUX的做法,那麼在WINDOWS裡的做法,我從VC知識庫看到了一篇文章如下:

在UTF-8,與UNICODE之間轉換的時候,用二進位運算,代替了字串的轉換。UTF-8一個漢字,用3個位元組,而UNICODE用2個位元組;對應關係如下:

UTF-8編碼:               [1,1,1,0,A5,A6,A7,A8],    [1,0,B3,B4,B5,B6,B7,B8],                  [1,0,C3,C4,C5,C6,C7,C8];

對應的UNICODE編碼:

[A5,A6,A7,A8,B3,B4,B5,B6],               [B7,B8,C3,C4,C5,C6,C7,C8]

因此我們只需進行位操作,即可達到目的;如:

      // 把UTF-8轉換成Unicode      void CChineseCodeLib::UTF_8ToUnicode(WCHAR* pOut,char *pText)      {      char* uchar = (char *)pOut;           uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);      uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);           return;      }
     // Unicode 轉換成UTF-8      void CChineseCodeLib::UnicodeToUTF_8(char* pOut,WCHAR* pText)     {      // 注意 WCHAR高低字的順序,低位元組在前,高位元組在後      char* pchar = (char *)pText;      pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));      pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);      pOut[2] = (0x80 | (pchar[0] & 0x3F));      return;     }     
     // 把Unicode 轉換成 GB2312      void CChineseCodeLib::UnicodeToGB2312(char* pOut,unsigned short uData)     {     WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);     return;     }          
     // GB2312 轉換成 Unicode     void CChineseCodeLib::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)     {     ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);     return;     }     
     //GB2312 轉為 UTF-8     void CChineseCodeLib::GB2312ToUTF_8(string& pOut,char *pText, int pLen)     {           char buf[4];           char* rst = new char[pLen + (pLen >> 2) + 2];                      memset(buf,0,4);           memset(rst,0,pLen + (pLen >> 2) + 2);                      int i = 0;           int j = 0;                 while(i < pLen)           {                   //如果是英文直接複製就可以                   if( *(pText + i) >= 0)                   {                           rst[j++] = pText[i++];                   }                   else                   {                           WCHAR pbuffer;                           Gb2312ToUnicode(&pbuffer,pText+i);                                                      UnicodeToUTF_8(buf,&pbuffer);                                                      unsigned short int tmp = 0;                           tmp = rst[j] = buf[0];                           tmp = rst[j+1] = buf[1];                           tmp = rst[j+2] = buf[2];                                                                                 j += 3;                           i += 2;                   }           }           rst[j] = ''/0'';              //返回結果           pOut = rst;                        delete []rst;                         return;     }     
     //UTF-8 轉為 GB2312     void CChineseCodeLib::UTF_8ToGB2312(string &pOut, char *pText, int pLen)     {         char * newBuf = new char[pLen];         char Ctemp[4];         memset(Ctemp,0,4);         int i =0;         int j = 0;                  while(i < pLen)         {                if(pText[i] > 0)                {                        newBuf[j++] = pText[i++];                                       }                else                                 {                        WCHAR Wtemp;                        UTF_8ToUnicode(&Wtemp,pText + i);                                        UnicodeToGB2312(Ctemp,Wtemp);                                            newBuf[j] = Ctemp[0];                        newBuf[j + 1] = Ctemp[1];                        i += 3;                            j += 2;                   }         }         newBuf[j] = ''/0'';                  pOut = newBuf;         delete []newBuf;                  return;      }

以上給出的代碼可以讓我們輕鬆的實現gb2312和UTF-8之間的轉換,我們可以從

http://www.nongnu.org/scew/

http://www.jclark.com/xml/expat.html

找到我們需要的EXPAT XML PARSER.當然,至於它的用法,大家看它的網站上的說明好了.我就不再廢話.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.