您的位置:首页 > 职场人生

由一道面试题引起的疑问与思考

2008-02-05 22:53 288 查看
由一道面试题引起的疑问与思考

前两天去一家公司面试,里面有一道XML的题目,题目没什么难的,但由于编码问题引发了一些问 题,我回来后尝试探索了一下
题目要求:把下面的XML文件用XSL转换成html表格显示出来,并按pubDate降序排列
 
 1  <? xml version="1.0" ?>
 2  <? xml-stylesheet type="text/xsl" href="books.xsl" ?>
 3  < books >
 4    < book  id ="1"  pubDate ="20050707" >
 5       < title > c# XML入门经典 </ title >
 6       < description > 编程人员必被的XML技能 </ description >
 7    </ book >
 8    < book  id ="2"  pubDate ="20050607" >
 9       < title > XSL编程精要 </ title >
10       < description > 从XML到HTML </ description >
11    </ book >
12    < book  id ="3"  pubDate ="20050607" >
13       < title > .NET framework框架程序设计 </ title >
14       < description > 框架程序设计 </ description >
15    </ book >
16  </ books >

当时我习惯的在桌面上建立文本文件,然后手工输入:
 
 1  <? xml version="1.0" ?>
 2  < xsl:stylesheet  version ="1.0"  xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" >
 3    < xsl:template  match ="/" >
 4       < html >
 5          < body >
 6             < table  border ="1pt" >
 7                < tr >
 8                    < td > BookId </ td >
 9                    < td > Title </ td >
10                    < td > Description </ td >
11                    < td > PubDate </ td >
12                </ tr >
13                < xsl:apply-templates  select ="//book" >
14                    < xsl:sort  select ="@pubDate"  order ="descending"   />
15                </ xsl:apply-templates >
16             </ table >
17          </ body >
18       </ html >
19    </ xsl:template >
20    < xsl:template  match ="book" >
21                < tr >
22                    < td >< xsl:value-of  select ="@id"   /></ td >
23                    < td >< xsl:value-of  select ="title/text()"   /></ td >
24                    < td >< xsl:value-of  select ="description/text()"   /></ td >
25                    < td >< xsl:value-of  select ="@pubDate"   /></ td >
26                </ tr >
27    </ xsl:template >
28  </ xsl:stylesheet >

注意:上面的XML代码由于FTB插入XML代码功能有问题,<后和>前都不能有空格,这也是XML Well-Format的要求.

然后在IE里浏览XML文件,提示:文本内容中发现无效字符;我检查过文件,文件没有非法字符,所以我觉得可能是XML编码问题,然后在顶部的指令里加入encoding="UTF-8",按理来说,UTF-8完全适合题涉及到字符集,但还是提示:文本内容中发现无效字符,而改成encoding="GB2312"就正常了,什么原因呢?

我回来尝试了一下,一般有两种情况:
情况1:
默认情况下,windows的notepad把文件保存为ANSI格式,在这种情况,设定不同encoding有不同的结果:
  encoding="windows-1252",不出错,但中文显示为乱码;
  encoding="GB2312" ,正常显示;
  encoding="UTF-8" ,出错,提示文本内容中发现无效字符 ;
情况2:
把xml文件在notepad另包存为UTF-8格式,
  encoding="windows-1252",出错,提示不支持从当前编码到指定编码的切换;
  encoding="GB2312" ,出错,提示不支持从当前编码到指定编码的切换;
  encoding="UTF-8" ,正常;
例外:不设置encoding的值,默认就是UTF-8,所以把这种情况归入UTF-8的情况.

那么如何来理解上面的两种情况呢?
 W3C定义了三条XML解析器如何正确读取XML文件的编码的规则:
 1,如果文挡有BOM(字节顺序标记,一般来说,如果保存为unicode格式,则包含BOM,ANSI则无),就定义了文件编码
 2,如果没有BOM,就查看XML声明的编码属性
 3,如果上述两个都没有,就假定XML文挡采用UTF-8编码

现在,让我们尝试用上面的三条规则来解释上面出现的情况:
情况1分析:
由于XML默认被保存ANSI格式,如果设置encoding="UTF-8",那么XML解析器就把文件以UTF-8格式 来解析,由于文件的实质格式是ANSI,而ANSI和UTF-8除了其中128个字符的编码相同外,其他的 都不相同而被解析器认为无效字符,所以出现"文本内容中发现无效字符"的错误了;设置为 encoding="windows-1252",解析器以windows-1252来解析,ANSI其实就是windows-1252,所以编 码相同,解析器能顺利解析,但中文出现乱码又如何理解呢?windows-1252是单字节字符集,而 中文是需要双字节编码的,所以只能解析为乱码。设置encoding="GB2312"能够正常显示,那又如 何理解呢?因为GB2312是双字节的中文简体字符集?前面不是说文件的实质格式是单字节的ANSI 吗?这就是矛盾的地方。

情况2分析:
由于文件被保存为UTF-8(Unicode的其中一种编码方式),所以文件包含BOM,按照W3G的规则来解释 ,XML解析器将以UTF-8解析XML而忽略encoding的设置。可实际上是不能忽略encoding的设置的, 否则无法解释情况2出现的现象。

遗留问题:

 

 

说一下我的理解:
首先,记事本里的ANSI编码保存方式并不是指使用ANSI编码方式。而是指用缺省code page所对应的编码方式。比如,中文Windows系统的缺省code page一般对应GBK,那么你用ANSI方式保存,内码就是GBK。

基于以上理解,1和2情况都好解释:
1:GB2312为GBK的子集,所以能正常显示。其他两种情况对应字符集都不相同,所以不能正常显示

2:UTF-8是不需要BOM的,(也可加上,为:“EF BB BF”,只是为了标明是UTF-8方式)

另:记事本的unicode保存方式其实是UTF-16(Little-Endian),是unicode的一种编码实现方式。它采用双字节的处理方式(16位)。但unicode并不只是双字节的,目前它有两种规范,UCS-2和UCS-4。也就是说,完整表示unicode可能需要4个字节(UTF-8更多,需要6个字节,因为它是单字节处理方式,需要多余位标示该字符在unicode中的对应范围)
本文并没能完全分析情况1,2的现象。不知道大家是如何理解这些情况的呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息