Category Archives: 软件技术

软件相关的技术,问题,经验和故事

又上了名字空间的套

在做一个XML的XSL,原XML如下: <?xml version="1.0" encoding="utf-16"?> <book version="5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://docbook.org/ns/docbook">   <info>     <title>test</title>     <author>       <personname>         <othername>Unknown</othername>       </personname>     </author>     <bibliosource>Unknown</bibliosource>   </info> </book> 制作的XSL: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">     <xsl:template match="info">         <xsl:value-of … Continue reading

Posted in Jeebook, XML | Tagged , , | Leave a comment

XHTML解析的实体问题

我在《集成Html Tidy》一文中说过使用HtmlTidy转换HTML以方便使用XML解析器解析,事实上,并没有那么简单,随便解析几个XHTML就会碰到解析异常的问题,错误是“Reference to undeclared entity ‘nbsp’”。 查找原因发现,在XML中,除了&lt; &gt; &amp; &apos; &quot;以外,其他如&nbsp;之类的实体必须通过DTD或其他方式定义。Html Tidy转换出的XHTML并没有显式定义这些实体,而是采用类似以下的定义: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 在这个DTD中会定义如&nbps;之类的实体,但由于需要到W3C的网站上去获取这些定义,所以XML解析器默认会忽略这些定义,就导致没有定义的异常。 不过在.net中提供了XmlResolver类帮助处理这种情况,而我们需要做的就是重写这个类,并将XHTML中定义的DTD重新指向我们指定的某个位置,如上的情况操作如下: 1. 下载http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 2. 将下载的dtd作为资源放入程序中 3. 重写XmlResolver类,增加判断,当传入的路径为"-//W3C//DTD XHTML 1.0 Transitional//EN" 时就以流方式返回资源中的DTD 4. 创建XmlReader,并将重载的XmlResolver设置在XmlReader中 5. 使用该XmlReader装载解析XHTML 完成以上步骤,再解析XHTML就不会再有异常出现了。当然XHTML的DTD定义不止这一种,为了兼容起见,最好将所有的DTD定义都按以上的步骤加入程序中。 具体实现代码可以参考我的开源项目:Page Releaser

Posted in PageReleaser, 我爱开源 | Tagged , , | 1 Comment

UrlRewritingNET实现URL Rewrite

在asp.net中实现URL Rewrite,除了IIS本身带的URL Rewrite Module以外,还有很到其他的解决方案,比如UrlRewritingNET。 UrlRewritingNET号称除了文件扩展名Rewrite需要IIS支持以外,其他所有操作都不需要IIS设置,这当然对虚拟主机的网站来说是非常便利的。 下面看看怎么来部署UrlRewritingNET: 1. 首先将下载的dll放置到bin目录 2. 修改Web.config,增加UrlRewritingNET的相关配置如下: <?xml version="1.0"?> <configuration>     <configSections>         <section name="urlrewritingnet"                  requirePermission="false"                  type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter"/>     </configSections>     <urlrewritingnet rewriteOnlyVirtualUrls="true"                    contextItemsPrefix="QueryString"                      defaultProvider="RegEx"                      xmlns="http://www.urlrewriting.net/schemas/config/2006/07">         <rewrites>             <add name="category"                  … Continue reading

Posted in Jeebook, 软件技术 | Tagged , | Leave a comment

HTML页面之间的参数传递的局限性

动态网页传递参数比较简单,如果想在HTML之间传递参数就需要一点技巧,摘录两种方法如下: 采用字符串解析的: /* *函数功能:从href获得参数 *sHref:   http://www.cscenter.com.cn/arg.htm?arg1=d&arg2=re *sArgName:arg1, arg2 *return:  the value of arg. d, re */ function GetArgsFromHref(sArgName) {      var sHref= document.location.href;     var args  = sHref.split("?");     var retval = "";     if(args[0] == sHref) /*参数为空*/     { … Continue reading

Posted in Jeebook, 软件技术 | Tagged , , | Leave a comment

实现HTML的简单压缩

PageReleaser需要一种HTML的压缩算法,Google了很久,发现如果只是简单去除空白和注释的话,使用XLinq就可以轻易的实现 先看看MSDN是怎么说的: 一种常用方案是读取缩进的 XML,在内存中创建一个没有任何空白文本节点(即不保留空白)的 XML 树,对该 XML 执行某些操作,然后保存带缩进的 XML。在序列化带格式的 XML 时,只保留 XML 树中有意义的空白。这是 LINQ to XML 的默认行为。 另一个常见的情况是读取和修改已经有意缩进的 XML。您可能不想以任何方式更改这种缩进。若要在 LINQ to XML 中执行此操作,您要在加载或解析 XML 时保留空白,并在序列化 XML 时禁用格式设置。 简单的说,XDocument载入时,默认使用LoadOptions::None,自动去掉XML的空白;保存时,默认使用SaveOptions::None,自动格式化XML。 也就是说,使用XDocument将一个HTML文档打开什么也不作就保存,其实等于实现了HTML的格式化。 而如果在保存时,使用SaveOptions::DisableFormatting参数,看似要保存XML的空白,由于载入时所有空白都被删掉了,其实等于删除了所有空白,于是去掉空白就这样实现了。 至于删掉注释也很简单,只是需要注意,一般页面嵌入JavaScript会使用注释节点包裹,需要例外处理。 整个HTML压缩代码如下: var nodes = from s in doc.DescendantNodes() where … Continue reading

Posted in C#, PageReleaser, XML | Tagged , , | Leave a comment

开源项目:Page Releaser

使用js框架+Ajax模式的开发,总会造成大量的js文件导致网站传输效率降低,尤其在网络状况不佳的环境很容易出现整个网页无法使用,就如IE的那个经典错误,对象不支持此属性或方法。 js压缩合并的工具很多,我也基于JsMin做过JsMin#。不过因为调试的需要,仍然需要维护一个调试用得HTML,里面引用所有未压缩的js;再维护一个发布用得HTML,用来引用合并后的js。每次更新网页都非常不方便。 此后,开始构思更好的方法,于是有了Page Releaser的构想。 Page Releaser借鉴了C++中Release的概念,通过解析HTML提取js和css信息,并对它们进行压缩,合并,嵌入,再依照处理结果重新构建HTML,最终生成一套完整的发布版本。之所以叫Page,是因为它每次只处理一个HTML。(本来打算叫WebReleaser,但多HTML会牵涉到资源网页间共用的问题,比较复杂,自动化结果会很难评估。不过好在,像ExtJS这样的大型框架,任何应用一个HTML就够了:) Page Releaser的终极目标是将包含一个HTML,N个JS,N个CSS,N个图片的网站,最终压缩成一个HTML和一个图片,以最大的减少浏览器因为建立连接造成的效率浪费。 当然,浏览器建立最少的连接并不意味着网站就有最优化的效果,比如一张1000*1的图片和一张1*1000的图片无论怎么合并,生成新图片都会比原来的图片大得多,所以Page Releaser也提供各种参数以便产生针对性的最好效果。 目前放出的版本只是实现了js的压缩,合并,嵌入以及css的合并,嵌入,其他功能将逐步加入 Page Releaser安装 当然按照惯例,小工具一概开源,大家也可以自行下载代码编译: Page Releaser源码

Posted in PageReleaser, 我爱开源 | Tagged , , | Leave a comment

RichTextBox实现图文并茂

怎么在RichTextBox中插入图片,网上广为流传的方法是,通过剪贴板粘贴的方法,代码如下: openFileDialog1.Filter = "图片文件|*.jpg|*.bmp|*.png|所有文件|*.*"; if (openFileDialog1.ShowDialog() == DialogResult.OK)      {          Clipboard.SetDataObject(Image.FromFile(openFileDialog1.FileName), false);          this.RichTextBox.Paste();       } 不过,用剪切粘贴实现图片插入显然是偷巧之作,显得别扭还不够灵活。 其实RichTextBox本身处理的是RTF,只要能按照RTF格式的要求对图片文字进行处理,就可以简单的实现图文并茂。何况已经有处理的很好的控件,比如ExRichTextBox ExRichTextBox实现文本图片的插入,但没有提供链接的支持,尝试添加以下代码: StringBuilder sb = new StringBuilder(); sb.Append(RTF_HEADER); sb.Append(@"{\fonttbl{\f0\fnil\fcharset" + Font.GdiCharSet.ToString() + " " + EncodeAnsi(this.Font.Name) + ";}}"); sb.Append(@"\f0\fs" + (int)Math.Round((2 * … Continue reading

Posted in C# | Tagged , , , | Leave a comment

C#实现文件关联

和其他语言一样,C#实现文件关联同样需要直接操作注册表,即按规则分别设置文件扩展名,文档类型说明,友好名称,图标,调用方法等键值即可,网上随便查查就可以写出以下的代码。 using Microsoft.Win32; RegistryKey key = Registry.ClassesRoot.OpenSubKey(".jb"); if (key == null) {     key = Registry.ClassesRoot.CreateSubKey(".jb");     key.SetValue("", "Jeebook.Reader.jb");     key.SetValue("Content Type", "application/jb");     key = Registry.ClassesRoot.CreateSubKey("Jeebook.Reader.jb");     key.SetValue("", "Jeebook Document");     RegistryKey keySub = key.CreateSubKey("DefaultIcon");     keySub.SetValue("", System.Windows.Forms.Application.StartupPath + … Continue reading

Posted in C#, 软件技术 | Tagged , , , | Leave a comment

SVN代码冻结

如何用SVN实现代码冻结? 以TortoiseSVN为例: 1. 获取代码库的最新版本 2. 使用Get Lock锁定根目录,目录下所有文件也会被锁定,这时对任何已锁定文件的提交都会导致错误 3. 需要修改或提交时,先使用Release Lock释放指定的目录或文件 4. 等待对方提交后,Update本地代码。注意,如果锁定的代码不是最新版本,锁定时会提示错误并失败 5. 重新使用Get Lock锁定被解锁的文件或目录 SVN的锁定功能有点类似VSS最早被check out的文件无法check in一样的机制,在配置上,可以制定某种类型的文件自动锁定,不过仅从代码冻结的角度看,如上的方法已经足够用了 P.S. 据说使用锁定会影响TortoiseSVN获取代码的性能,经确认,的确很慢,所以如果可以的话,最好还是改哪个文件取哪个文件的好。 P.S. TortoiseSVN会把锁定的状态保存到本地,所以,如果你不小心删掉本地代码,重新获取的时候会发现所有文档的状态都是解锁状态,但无法提交或再次锁定,这时只能通过TortoiseSVN代码浏览器的方式破除锁定,但破除锁定的操作只能针对单个文件,会比较麻烦。关于这个问题,目前除了小心没有找到更好的办法,也不确定是不是TortoiseSVN得BUG。

Posted in 软件技术 | Tagged , , | Leave a comment

ExtJS的效率问题

由于ExtJS的GridPanel在分页状态下只能对当前页面按列排序,为了方便排序一时偷懒就把PagingToolbar给去掉了 压力测试时,发现当GridPanel包含1000条纪录时,整个界面的反应速度都非常慢,有时延迟甚至达到17秒。 开始以为是因为数据传输过大导致的延迟,之后又发现即使只是打开没有任何传输的界面仍然会有很长时间的延迟,已经可以确认是页面的问题了。 其实想想也是,ExtJS只是通过js动态的把HTML的tag依次加入到原有的DOM树中,当有1000条纪录的GridPanel存在时,可以想见当前浏览器中要处理的DOM树何其的庞大,效率瓶颈是必然的,何况处理如此庞大数据的还是js这种脚本弱语言。只不过一般情况下,ExtJS类似桌面程序的样子容易让我们想当然的认为效率不是问题。 可惜的是这段代码是基于ActiveX技术的实现,否则倒是可以测试一下三大浏览器在js处理问题上分个高下:) P.S. 理论上,同样的硬件同样的1000条纪录在服务器端生成同样的HTML返回,应该会比在客户端js根据数据解析后生成效率要高。

Posted in ExtJS, 软件技术 | Tagged , , | Leave a comment