免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 12562 | 回复: 16
打印 上一主题 下一主题

xml文件的中文问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-06-17 20:31 |只看该作者 |正序浏览
PERL的xml:arser 有支持gbk或gb2312 charset 的吗?
缺省只有big5。

读包含中文的xml文件,我这样写
     
<?xml version="1.0" encoding="big5"?>;

<ETLConfig>;
    <database S="test" U="测试" P="测试"/>;
    <database S="aaa" U="aaa" P="aaa"/>;
</ETLConfig>;

输出的是乱码。
use XML::Simple;
use Data:umper;

my $config = XMLin('c:/server.xml');          # load the file

print Dumper($config);
use bytes;

print  $config->;{database}[0]->;{U};                             
no bytes;

论坛徽章:
0
17 [报告]
发表于 2004-04-21 15:33 |只看该作者

xml文件的中文问题

lgjut  :
这个包http://www.hunterpro.net/projects/xml/index.html
我下载下来,怎么解压出错了!

论坛徽章:
0
16 [报告]
发表于 2003-11-18 09:57 |只看该作者

xml文件的中文问题

楼上的大侠,请指点怎么做. 我也遇到同样的问题.

论坛徽章:
0
15 [报告]
发表于 2003-06-25 04:44 |只看该作者

xml文件的中文问题

原帖由 "lgjut" 发表:
问题终于解决了。:)

搜到了支持GB2312的expat,
http://www.hunterpro.net/projects/xml/index.html
改了一下接口,在perl中试用了一下,它不再报错了。
以后有时间再写一个正式的补丁。
   


期待补丁, ;-)

论坛徽章:
0
14 [报告]
发表于 2003-06-24 21:16 |只看该作者

xml文件的中文问题

问题终于解决了。

搜到了支持GB2312的expat,
http://www.hunterpro.net/projects/xml/index.html
改了一下接口,在perl中试用了一下,它不再报错了。
以后有时间再写一个正式的补丁。

论坛徽章:
0
13 [报告]
发表于 2003-06-24 12:04 |只看该作者

xml文件的中文问题

谢谢apile的指点。

出错原因:因为调用expat.xs 中的 parse_stream
而parse_stream又调用XML_ParseBuffer
而XML_ParseBuffer调用processor
而processor被初始化成prologInitProcessor

prologInitProcessor调用initializeEncoding
                          initializeEncoding正常应该返回XML_ERROR_NONE
                          而initializeEncoding调用handleUnknownEncoding
                          而在expat.xs中的XML_ParserCreate有 XML_SetUnknownEncodingHandler(RETVAL, unknownEncoding, 0)
                          而unknownEncoding正常应该返回1,的确返回了1
prologInitProcessor  调用的下一个函数是handleUnknownEncoding  函数代码如下:

if (unknownEncodingHandler) {
    XML_Encoding info;
    int i;
    for (i = 0; i < 256; i++)
      info.map = -1;
    info.convert = NULL;
    info.data = NULL;
    info.release = NULL;
    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
                               &info)) {
      ENCODING *enc;
      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
      if (!unknownEncodingMem) {
        if (info.release)
          info.release(info.data);
        return XML_ERROR_NO_MEMORY;
      }
      enc = (ns
             ? XmlInitUnknownEncodingNS
             : XmlInitUnknownEncoding)(unknownEncodingMem,
                                       info.map,
                                       info.convert,
                                       info.data);
      if (enc) {
        unknownEncodingData = info.data;
        unknownEncodingRelease = info.release;
        encoding = enc;
        return XML_ERROR_NONE;
      }
    }
    if (info.release != NULL)
      info.release(info.data);
  }
  return XML_ERROR_UNKNOWN_ENCODING;
  
  
执行 enc = (ns
             ? XmlInitUnknownEncodingNS
             : XmlInitUnknownEncoding)(unknownEncodingMem,
                                       info.map,
                                       info.convert,
                                       info.data);
后enc应该<>;0 这样才能return XML_ERROR_NONE
实际上只有XmlInitUnknownEncoding函数存在

XmlInitUnknownEncoding(void *mem,
                       int *table,
                       CONVERTER convert,
                       void *userData)
{
  int i;
  struct unknown_encoding *e = (struct unknown_encoding *)mem;
  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
    ((char *)mem) = ((char *)&latin1_encoding);
  for (i = 0; i < 128; i++)
    if (latin1_encoding.type != BT_OTHER
        && latin1_encoding.type != BT_NONXML
        && table != i)
      return 0;
  for (i = 0; i < 256; i++) {
    int c = table;
    if (c == -1) {
      e->;normal.type = BT_MALFORM;
      /* This shouldn't really get used. */
      e->;utf16 = 0xFFFF;
      e->;utf8[0] = 1;
      e->;utf8[1] = 0;
    }
    else if (c < 0) {
      if (c < -4)
        return 0;
      e->;normal.type = (unsigned char)(BT_LEAD2 - (c + 2));
      e->;utf8[0] = 0;
      e->;utf16 = 0;
    }
    else if (c < 0x80) {
      if (latin1_encoding.type[c] != BT_OTHER
          && latin1_encoding.type[c] != BT_NONXML
          && c != i)
        return 0;
      e->;normal.type = latin1_encoding.type[c];
      e->;utf8[0] = 1;
      e->;utf8[1] = (char)c;
      e->;utf16 = (unsigned short)(c == 0 ? 0xFFFF : c);
    }
    else if (checkCharRefNumber(c) < 0) {
      e->;normal.type = BT_NONXML;
      /* This shouldn't really get used. */
      e->;utf16 = 0xFFFF;
      e->;utf8[0] = 1;
      e->;utf8[1] = 0;
    }
    else {
      if (c >; 0xFFFF)
        return 0;
      if (UCS2_GET_NAMING(nmstrtPages, c >;>; 8, c & 0xff))
        e->;normal.type = BT_NMSTRT;
      else if (UCS2_GET_NAMING(namePages, c >;>; 8, c & 0xff))
        e->;normal.type = BT_NAME;
      else
        e->;normal.type = BT_OTHER;
      e->;utf8[0] = (char)XmlUtf8Encode(c, e->;utf8 + 1);
      e->;utf16 = (unsigned short)c;
    }
  }
  e->;userData = userData;
  e->;convert = convert;
  if (convert) {
    e->;normal.isName2 = unknown_isName;
    e->;normal.isName3 = unknown_isName;
    e->;normal.isName4 = unknown_isName;
    e->;normal.isNmstrt2 = unknown_isNmstrt;
    e->;normal.isNmstrt3 = unknown_isNmstrt;
    e->;normal.isNmstrt4 = unknown_isNmstrt;
    e->;normal.isInvalid2 = unknown_isInvalid;
    e->;normal.isInvalid3 = unknown_isInvalid;
    e->;normal.isInvalid4 = unknown_isInvalid;
  }
  e->;normal.enc.utf8Convert = unknown_toUtf8;
  e->;normal.enc.utf16Convert = unknown_toUtf16;
  return &(e->;normal.enc);
}

发现是因为:
  for (i = 0; i < 128; i++)
    if (latin1_encoding.type != BT_OTHER
        && latin1_encoding.type != BT_NONXML
        && table != i)
      return 0;

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
12 [报告]
发表于 2003-06-24 08:43 |只看该作者

xml文件的中文问题

我是看XML:arser::Expat這個module的說明文件..
裡面有說load_encoding所要load的enc並不能放在
XML/Parser/Encoding中...
所以我用它的方式,將gb2312.enc放在別的地方...
利用他給的範例去load gb2312的內容。
但是從回傳值可以看到GB2312...
但是將%Encoding_Table的資料一個一個找出來看,
卻發現裡面是空的..
表示LoadEncoding可以讀到enc中GB2312 ,
但是卻無法存到%Encoding_Table中..
我看了一下Expat/Expat.xs...裡面..實在看不出個所以然來..
所以才需要找高手看看..可能GB2312.enc編碼出來的二進制
格式不是LoadEncoding這個c function要的...
我現在很忙..沒時間繼續follow 下去..你再看看吧...

论坛徽章:
0
11 [报告]
发表于 2003-06-23 23:38 |只看该作者

xml文件的中文问题

编译了一下,没发现XML_LoadEncoding有什么问题。
于是往回找,
在sub load_encoding 的结尾处作了一个%Encoding_Table的Dumper
$VAR1 = 'GB2312';
$VAR2 = bless( do{\(my $o = 30574612)}, 'XML:arser::Encinfo' );
当charset是big5时

$VAR1 = 'BIG5';
$VAR2 = bless( do{\(my $o = 30593524)}, 'XML:arser::Encinfo' );

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
10 [报告]
发表于 2003-06-23 08:41 |只看该作者

xml文件的中文问题

應該是Expat/Expat.xs裡面...XML_LoadEncoding function...
我C的功力還沒那麼好...所以可能得找C的高手幫忙看看..
因為他會產生一個Expat.so的share object在auto/XML/Parser/Expat目錄下,
可以直接蓋掉上面目錄中的那個...或者重新安裝XML:arser...

论坛徽章:
0
9 [报告]
发表于 2003-06-22 11:59 |只看该作者

xml文件的中文问题

LoadEncoding函数是C代码。
在XML-Parser-2.31的Expat.c中。
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP