一、Open Office开发资料
直接操作WordMl在实现复杂些的操作时,总有些不方便,因此就有了一个把wordML解析到类中的想法,顺便把word转换成Html。
WordMl从word2003开始就比较完善了,到06年十月形成了Open Office标准。word2007已经是符合此标准的格式了。
Word2007的WordprocessingML比03的增加了许多新标记,增加了组,重新定义了XSD,但是元素基本没有变化,完全兼容03。(我现在还没有在07中发现03没有的元素,唯一的一个是在07中没有找到wx名称空间)。
现在关于WordprocessingML的资料很少,多是写入门级别的例子,基本上只有官方的文档可以参考
现在网上能找到一个WarstarDev.Office2k7的Office Open XML C# 类库(未完成),它的目标是把Open Office解析到类中,但是我发现它对Open office 的解析是有许多错误的(下面会提到)。
开发WordML的必备工具:
最重要的就是一个好的xml编辑器,推荐XmlSpy。
其次WordXMLToolbox工具可以在2003下面使用,可以提供一些辅助,通过他还可以改进你对word的操作。
二、类库要实现的功能:
1、 把WordMl解析到类
2、 通过类生成、修改Word
3、 把Word转换到Html格式
4、 对word简单操作(替换、查找等)的封装
最终目标是不差于google office的word部分,支持word2003和2007。
三、解析WordMl的几种方式
1. 最简单的是用反射,WarstarDev.Office2k7就是采用这种方式。但是反射决定了这种方式的不足是性能和解析的灵活性。
2. 序列化,用它解析word是不现实的,因为它的灵活性还赶不上反射,每个类还要打上许多标记。这种方式可以用来当作其他方式的补充。
3. DOM、xpth,WordML本来就是xml格式的,Dom的结构决定了这种方式是最灵活的,也是功能最强大的一种,但是这种方式相较反射会复杂许多,也很耗费内存。
4. SAX,在.net中可以用xmlreader、xmlwriter,这种方式是1、3的折中方案。
5. 正则表达式,也是其他方式的补充。正则是逐字解析的,我怀疑它的效率可能还赶不是DOM,灵活性也差许多。
因此,如果只是把word转换到类中第一种方式是最简单的,是首选方式。但是这种方式在回写时回出现问题,因此WarstarDev.Office2k7采用了xmlWriter。如果综合考虑第三种是最合适的,DOM、xpath决定了这种方式不论是从wordml到类还是从类到wordml都是最方便的,也是最灵活的。
我在项目中采用的就是第三种方式,这种方式能够随机的解析word中的某个部分,也可也解析整个文档,但是这要求类的结构要考虑的特别周到,否则随着解析量的增加,组合方式的变化,整个项目结构会乱到不能继续下去的程度。我在这个项目中许多时间都花在了结构的调整和解析方式的选择上,如某个元素是自己负责自己的解析还是让父元素负责还是它的兄弟、子节点,选错了方式不但结构会变遭,工作量也会变大。
四、wordMl映射到类的方式
1、根据xml写类,在序列化时,这是最常用的方式。但是要解析的不是某个单一word文档,这决定不能采用这种方式。
2、用xsd.exe。word xsd的复杂性决定这种方式是很难的,再加上xsd生成的垃圾代码过多、它不会映射group等特点,这也是不可取的,如果用它类库就几乎废掉了。
3、自己根据xsd写类,这是最灵活的,也是这个项目的难题之一。
五、Group的映射方式:
ComplexType、SimpleType、Group可以映射到对应的类,前两种类型直接映射就可以了,但对于Grouop会有不同的处理方式。group在xml中主要用于元素重用,减少重复,在类中类似的功能可以用组合和继承实现,从类设计角度组合似乎更合适些,但是从WordMl角度考虑,继承是唯一选择,原因是如果用组合,类库的调用者不但要熟悉Open office 格式还必须了解word的xsd,从调用者考虑这样的设计也是不合适的。如果用继承可以对调用者隐藏掉组的存在,这也是xsd中组的本意。因为.net只支持单继承,这样就要求这些类都不能再有父类,继承自多个group的类型也要做些取舍,总之是一个权衡的过程。