• 从写组件说Xml——实现(五)


    1.实现接口

        前面一篇已经确定了接口,并且已经生成了类,但是这些类显然还不完整,因为这些类没有实现任何接口。

        不过,在实现接口之前,必须要注意的是ms的这一段警告:

    image

        这里清楚地说明了直接修改这段代码的一个风险:如果xsd发生变化了,那么再次用xsd.exe生成代码时,所做的修改讲丢失。这时要么手工迁移,要么就再写一遍,无论哪种,都是无法接受的。

        因此,实现接口的代码不能放在生成的pptx.cnblogs.cs中。这里借助c# 2.0就提供的partial关键字,把对类型的修改放到另一个文件中(这里要注意namespace,如果不相同,就会被认为是两个不同的类型)。所以,新添加的文件至少应该是这样的:

    image

        然后实现接口:

    image

    2.具体实现…

        限于篇幅,以及和主题的相关度,此处省略具体实现。

    3.修改pptx

        pptx的open xml format说白了就是xml+zip的格式,所以修改xml就可以修改呈现给终端用户的pptx。

        现在又要感谢ms的Linq to Xml,可以把原来操作非常麻烦的Xml DOM方式完全扔到一边,用简洁的Linq语法完成当初几十行DOM代码才能完成的辛苦工作。

        这里以修改pptx中的文本内容为例(因为这个最简单,其它的都会比较复杂,例如chart需要同时修改缓存数据和真实数据,真实数据又在一个embed xlsx里面,对于不熟悉open xml format的人来说,有点少儿不宜的感觉)。

        先来看看文本内容在pptx中的xml到底是什么样子的,为了看xml,先做一个pptx的模板,如下:

    image

        保存为sample.pptx,然后到目录下面,把文件名修改成sample.pptx.zip,并解压,找到这个目录:

    image

        用vs2008打开slide1.xml,可以看到:

    image

        几乎所有内容都在第二行,估计没有人愿意看这样的xml。。。别急,利用vs2008的格式化文档的功能(快捷键为Ctrl+K,Ctrl+D):

    image

        瞬间,就可以获得一个完全格式化好的xml,然后再找到里面的placeholder:

    image

        可以看到placeholder在a:t节中出现,至于其它的节,暂时忽略它们。

        注意先看namespace:a,a的定义为:

    image

        所以,需要在代码里面预先定义namespace:

    image

        乍一看这个语句是不是有点怪,左边的类型是XNamespace,而右边怎么是个字符串?别急,来看看XNamespace的定义:

    image

        可以发现XNamespace里面定义了从string的隐式转换,所以上面那个语句是合法的,另外,还有一个很重要的运算符重载+,输入是XNamespace和string,输出为XName,这个运算符重载将在后面非常广泛的用到。

        下面来看看TextModification的大体结构吧:

    image

        这里用到了ExecutionContext的两个扩展方法,GetCurrentSlideDocument和SaveCurrentSlideDocument这两个方法,分别用于取得XDocument的实例和保存这个实例,而中间的todo就是实现的重点。

        还记得前面的a:t吗?需要到整个xml文档中去查找a:t的节点,怎么找哪?最简单的当然是用Linq to Xml:

    image

        Descendants方法代表着XPath的子孙轴(关于Xml的13个轴可以参考w3schools,为了方便起见,就来个截图:

    image

    ),也就是查找Xml文档下面的所有节点。

        但是前面的Linq找到的是所有的a:t,而不是包含特定内容的a:t,所以需亚修改一下Linq:

    image

        节点找到了,但是还需要修改它们:

    image

        剩下一个问题,就是realValue怎么取得哪?

        TextModification有一个value属性是Expression类型的,而Expression有实现了IExpression接口,也就是有一个GetValue的方法,那么realValue就可以这么写:

    image

        所以整个类就是:

    image

        到现在为止,这个组件基本上已经可以工作了,但是,不得不说一个问题,如果Xml配置错了,如何差错哪?下一篇将讨论一下这个问题。


    上一篇:从写组件说Xml——接口和初步实现(四)

    下一篇:从写组件说Xml——改良(六)


  • 相关阅读:
    BZOJ3473: 字符串
    BZOJ1088: [SCOI2005]扫雷Mine
    跪啃SAM
    BZOJ3932: [CQOI2015]任务查询系统
    BZOJ3545: [ONTAK2010]Peaks
    06.约束
    05.数据表的创建与简单操作
    04.数据库的创建
    安卓6.0后运行时权限封装
    OkGo使用缓存
  • 原文地址:https://www.cnblogs.com/vwxyzh/p/1578157.html
Copyright © 2020-2023  润新知