Archive for the 'T' Category


Hidden White Space 2

处理XML的过程中,有些Parser会strip掉空格,比如
输入是<a> </a>,而输出则有可能变为<a/>

这种“潜移默化”的转变有时候只发生在表示层,就是显示的XML文件和实际的数据不一致,比如IE就会帮我们做这种事情…
今天算是学乖了,比较稳妥的做法就是处理数据的时候都strip()或者trim()一下,安全第一…这种由于数据来源不稳定而要用更额外的方法来确保鲁棒性的做法实在是很值得商讨。其实有好也有坏。想在不影响性能的前提下,还是做一下吧,至少自己安心。

总结一下,就是不要相信所看见的所听见的…不一定是真的…

XSLT 1.0:用call-template还是apply-templates? 0

在五一放假前和Mike讨论到这个问题,之前我用了比较多的call-template,后来说着说着,突然发现apply-templates在大部分的场景下比call-template好用,也更安全一些。

比如,apply-templates可以通过select属性来选择具体要匹配的node-set,如果不存在这样的node-set,就不进行转换,这就比call-template安全了一些,因为后者是直接调用,不管存不存在某些节点;其次,apply-templates和call-template一样,可以通过<xsl:param/>接受参数;此外,当我们定义多个template时,这些templates不可以有重复的name,但可以有重复的match,重复的template通过priority来确定该用哪个template来进行转换,如果多个template有相同的priority的话,则选择最后出现的那个。

似乎apply-templates功能比call-template强。就目前我所用到的普通转换来说,用apply-templates是比较安全的,并且可读性也会高一些。但是在XSLT 1.0中,如果想要实现像XSLT 2.0中function一样的功能的话,用call-template就比较方便了,比如递归调用(Recursive function)。下面是一个例子:

<xsl:template name=”longest-speech” as=”element(SPEECH)?”>
<xsl:param name=”list” as=”element(SPEECH)*”/>
<xsl:choose>
<xsl:when test=”$list”>
<xsl:variable name=”first” select=”count($list[1]/LINE)” as=”xs:integer”/>
<xsl:variable name=”longest-of-rest” as=”element(SPEECH)?”>
<xsl:call-template name=”longest-speech”>
<xsl:with-param name=”list” select=”$list[position()!=1]“/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test=”$first gt count($longest-of-rest/LINE)”>
<xsl:value-of select=”$list[1]“/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$longest-of-rest”/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>

<xsl:template match=”/”>
<longest-speech>
<xsl:call-template name=”longest-speech”>
<xsl:with-param name=”list” select=”//SPEECH”/>
</xsl:call-template>
</longest-speech>
</xsl:template>

待转换的xml是:

<?xml version=”1.0″?>
<SCENE><TITLE>SCENE I. Venice. A street.</TITLE>
<STAGEDIR>Enter RODERIGO and IAGO</STAGEDIR>

<SPEECH>
<SPEAKER>RODERIGO</SPEAKER>
<LINE>Tush! never tell me; I take it much unkindly</LINE>
<LINE>That thou, Iago, who hast had my purse</LINE>
<LINE>As if the strings were thine, shouldst know of this.</LINE>
</SPEECH>

<SPEECH>
<SPEAKER>IAGO</SPEAKER>
<LINE>’Sblood, but you will not hear me:</LINE>
<LINE>If ever I did dream of such a matter, Abhor me.</LINE>
</SPEECH>
etc.
</SCENE>

在关于使用call-template和apply-templates的性能差别上,Sam Judson (Wrox 技术编辑)有言:

In terms of raw performance xsl:call-template is likely to be faster, as you are calling a specific named template, rather than telling the XSLT processor to pick the template which best matches.

There are certainly things you can do with xsl:call-template that you can’t do with xsl:apply-templates, such as recursive templates which are very powerful.

xsl:apply-templates is however the more flexible and extensible, due to its combined use of the match patterns, modes and priorities.

我觉得概括的不错,言简意赅,就以此作为结尾吧。

使用float和background-color时出现的IE Bug 2

 译者序:在做系主页时遇到了这个问题,原作者说明了几种解决方法,觉得很不错,遂译之。
《IE CSS bugs when using floats and background-color》

如果一个div设置了background-color并且包含了具有float属性的元素(包括利用css的“float”属性或HTML中图片的“align”属性),IE浏览器就会解析错误——我IE6里一些样例页面的截图,对比它应该显现的页面

IE6有时候会隐藏div里的部分或全部元素(样例2和5的标题不见了);此外,在IE5和6中,如果容器被设定了属性position: relative, 则浮动的元素即会消失(参看样例4)。与其他文章不同的是,无需任何类型的间隔div就可以引发这个bug——这里所提及的例子中就没有用到任何相关的。操纵滚动条,往下滑会使丢失的内容被隐藏起来,再往上滚动的时候,丢失的内容就会显现出来,问题就解决了,但这不是一个可行的方法。

其他站点也注意到了这个问题,包括evolt.orgPosition Is Everything (the Peekaboo bug,链接中包含有更多的好玩的加法bug的动作 :) ),然后他们的解决方法是给不同的元素添加上属性position: relative;不管是那些消失的元素(evolt.org), 还是div容器以及包含在期内的所有浮动的元素(Position Is Everything)。这个不是直接的方法,因为你必须给所有可能的元素添加上position属性,并且不幸的是它又引发了另一个position:relative的bug,特别是Mac里的IE5

Position is Everything 与 evolt.org上的评论中还提到了另一个解决方法,那就是给div容器设定一个宽度,这在一定程度上能解决问题,但当该div有边框(border)与外补丁(margin),这个方法就不可能实现。

我的解决方法就比较简单:给那个div容器设定line-height属性。浏览器默认的行高(line height)好像是介于1.1-1.2之间,所以设置行高,使之在界面上不产生太大的变化,并能解决IE的bug。

为了说明问题和解决方法,对于IE6Firebird 0.6.1,我已经提供了六个样例(来源于evolt.org),还有一些页面的截图。

SML mode@Emacs 0

For 豆芽 for ella~
本文只是对Emacs下的SML-mode的配置的一个归纳以及翻译。

特别:是针对Windows下的配置,测试环境是WinXP SP2 + sml-mode 4.0 + Emacs

以下步骤不必按顺序执行,只要全部搞定就好了。

1、在Emacs的安装目录下(记为/*emacs*/)创建一个名叫site-lisp的子目录,如果已存在此目录则直接进入,在site-lisp目录下创建sml-mode目录,将你下载到的sml-mode包解压,复制里面所有的*.el文件到/*emacs*/site-lisp/sml-mode/下。
2、回到site-lisp文件夹下,编辑其中的site-start.el(如果没有的话就创建一个),
加入下面两行:

(add-to-list ‘load-path “/*emacs*/site-lisp/sml-mode”)
(load “sml-mode-startup”)

3、在PATH环境变量里包含SML编译器所在的目录(记为/*smlnj*/)。不要与sml-mode混淆
4、在C:/根目录下创建 .emacs 文件,在其中加入如下语句:

(setq load-path (cons “/*smlnj*/esml/” load-path))
(setq sml-program-name “/*smlnj*/bin/sml.bat”)
(setq sml-temp-file (make-temp-name “c:/temp/”))

; Syntax highlight
(global-font-lock-mode t)

OK,重启计算机就行了

打开Emacs,输入M-x sml-mode加载sml-mode
也可以直接输入M-x run-sml直接运行sml命令行窗口

P.S. M就用Alt吧,C就用Ctrl~
P.S. 在建立 .emacs 文件时可能会遇到一些麻烦,这时候就要用到ultraEdit来帮你了。