Web打印(3),面向对象JS编程:名字空间、类定义、继承、XML分析XmlParserBase基类实现

JavaScript代码,可以写在html里,也可以写在*.js文件里,大家没有有遇到引用了别人或自己的js文件时,发现定义了同样的变量,例如  var myobject;

由于JavaScript不像C#是强类型面向对象编程语言,更多的是像C的过程性结构化编程语言,随处定义变量,不可避免定义重复的变量名,这种重复的变量会导致严重的后果。所以,像C#一样,引入名字空间,将类定义到名字空间下,将变量定义到类中,不同类,定义了相同的变量互不受影响。 

面向对象最大的特点是抽象,最大优点是可复用性。既然是做打印元素,例如文本、标签、表格、图片、标尺等等,他们都有一个共同的特征,就是用XML去描述他们的属性特点,而分析XML后,获得一个打印对象。所以,XmlParserBase基类,抽象了XmlNode,作为类的属性,然后继承IXmlParser,实现接口定义的方法Parser(),分析XML后将相关标签写入Tag属性。由于后续要做大量的XML分析,所以,XmlParserBase基类,提供读取XML文件、XML字符串、XML节点的大量实用方法,供继承于XmlParserBase的子类使用。

  1. 字空间
      /*顶层命名空间*/
    var GoldPrinter =GoldPrinter || window.GoldPrinter || {};  
    /*子命名空间,可嵌套定义*/
    GoldPrinter.Drawing = GoldPrinter.Drawing || window.GoldPrinter.Drawing || {};  
    GoldPrinter.XmlParser = GoldPrinter.XmlParser || window.GoldPrinter.XmlParser || {}; 
           以上定义方法需要说明的是,以var GoldPrinter =GoldPrinter || window.GoldPrinter || {}为例,在重复定义GoldPrinter时避免被误覆盖掉。这样便能很方便的在多个文件里定义命名空间了。
  2. 类定义

     在上文 Web打印(2),打印核心架构--XML分析器及打印元素UML类图,接口及实现 中,其实已定义了IXmlParser类,并且用JS实现IXmlParser时,我们用到了如下语句:
    GoldPrinter.Throw.Msg("这是IXmlParser的Parse() ,接口类不要实例化!\r\n类型:" + typeof (this) + "真实类名" + this.GetType());

    这其实是调用于GoldPrinter名字空间下Throw类的一个Msg()方法。在后续的开发实现中,我们经常用于如下两个类,类似C#的静态类及静态方法。
    GoldPrinter.Throw = { Msg: function (message) { alert(message);} };
    GoldPrinter.MessageBox = { Show: function (message) { alert(message); }, Debug: function (message) { alert(message); } };

    Throw 类专门用于抛出异常时对话框,以提示开发者自己,MessageBox类用于显示对话框,用于提示客户端正在使用的操作用户。

    综述,IXmlParser类和Throw、MessageBox类,是两类不同写法的类。前者相当于是一个模版,可以复制出很多具有相同模版又可以改变模版中属性值的对象,这种类可实例化,只能使用实例对象;而后者,不用把模版复制直接可以使用。
  3. 继承
     

    /*
    * 表示分析处理用XML节点描述特征的对象的基类。
    */
    jXmlParser.XmlParserBase = function (xmlNode, tag) {

        //模拟C#,获取实例的类型,js如果不实现,都返回object
        this.GetType = function () { return "GoldPrinter.XmlParser.XmlParserBase"; };

        /*获取或设置描述对象特征的XML节点。*/
        this.XmlNode = "";
        /*获取或设置报表设计器的类型。*/
        this.ReportDesigner = jXmlParser.ReportDesigner.GoldPrinter;
        //标签
        this.Tag = {};

        if (xmlNode) {
            this.XmlNode = xmlNode;
        }
        if (tag) {
            this.Tag = tag;
        }

    //其他代码..

    }

    //继承于接口IXmlParser
    jXmlParser.XmlParserBase.prototype = new jXmlParser.IXmlParser();
    说明:
    jXmlParser.XmlParserBase = function (xmlNode, tag) {},用于定义一个类XmlParserBase ,他在GoldPrinter.XmlParser名字空间下,名字空间简写为jXmlParser。
    new jXmlParser.IXmlParser();表示创建IXmlParser的一个实例,将XmlParserBase的原型指向这个实例,这种实现继承的方法叫“原型链”法。

  4. XmlParserBase基类实现
    下面是其实现的全部JS代码。
     

    /*
    * 表示分析处理用XML节点描述特征的对象的基类。
    */
    jXmlParser.XmlParserBase = function (xmlNode, tag) {

        //#region 实现...

        //模拟C#,获取实例的类型,js如果不实现,都返回object
        this.GetType = function () { return "GoldPrinter.XmlParser.XmlParserBase"; };

        /*获取或设置描述对象特征的XML节点。*/
        this.XmlNode = "";
        /*获取或设置报表设计器的类型。*/
        this.ReportDesigner = jXmlParser.ReportDesigner.GoldPrinter;
        //标签
        this.Tag = {};

        if (xmlNode) {
            this.XmlNode = xmlNode;
        }
        if (tag) {
            this.Tag = tag;
        }

        /*对Tag进行分析,并附加上ReportDesigner,如果需要可以调用,一般无用。*/
        this.TagParse = function () {
            //#region 实现...
            var node = this.GetXmlNode();
            if (node) {
                //在属性中搜
                var otag = this.GetXmlNodeAttributeValue(node, "Tag");
                var oReportDesigner = this.GetXmlNodeAttributeValue(node, "ReportDesigner");
                //属性中没,在子节点中
                if (otag == "") {
                    otag = this.GetXmlNodeChildNodeValue(node, "Tag");
                }
                if (oReportDesigner == "") {
                    oReportDesigner = this.GetXmlNodeChildNodeValue(node, "ReportDesigner");
                }
                if (otag != "") {
                    this.Tag = otag
                }
                if (oReportDesigner != "") {
                    this.ReportDesigner = oReportDesigner;
                }
            }
            //#endregion 实现...
        };

        this.Parse = function () {
            //JS方法,不会调用基类已重写的方法。所以,继承此类的方法,重写Parse时,手动强制调用ParentClass.Parse()
            this.TagParse();   //C#中XmlParserBase是抽象类,所以没有放在模板方法中调用
            GoldPrinter.DebugModel.Msg("这是XmlParserBase的Parse() ,抽象类,请在子类实现Parse()方法!\r\n类型:" + typeof (this) + "真实类名" + this.GetType());
            return this;
        };

        var mXmlParseNode = undefined;
        /*获取XmlNode,当其为xml字符串时,自动将期转换为节点,将缓存,如果重新改变了XmlNode不使用缓存,则要调用SetXmlNode()*/
        this.GetXmlNode = function () {

            var node = mXmlParseNode;
            if (node == undefined) {
                node = this.XmlNode;
            }
            else {
                return mXmlParseNode;
            }

            if (node && typeof (node) == "string") {
                node = this.SelectRootNode(node, false);
                //缓存
                mXmlParseNode = node;
            }

            return node;
        };

        /*设置XmlNode属性,并清空节点缓存*/
        this.SetXmlNode = function (xmlNode) { mXmlParseNode = undefined; this.XmlNode = xmlNode; };

        /*用XML文件设置元素,XmlNode属性默认取其根结点,第一参数表示表示金质打印通的元素集合文件或文件文本内容,第二参数为true,表示文件名,否则为文件具体内容*/
        this.SelectRootNode = function (xmlFileName, isXmlFileOrContext) {
            //#region 实现...

            //<?xml version="1.0" encoding="utf-8"?>
            if (xmlFileName == undefined) return;

            var isXmlContext = xmlFileName;

            if (isXmlFileOrContext) {
                if (window.XMLHttpRequest) {// IE7+, Firefox, Chrome, Opera, Safari
                    xmlhttp = new XMLHttpRequest();
                }
                else {//IE6, IE5
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                xmlhttp.open("GET", isXmlContext, false);
                xmlhttp.send();
                mXmlDoc = xmlhttp.responseXML;
            }
            else {
                /*
                //不是XML文件,而只是一个节点,则加上 \u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e
                if (isXmlContext.indexOf("<?xml") < 0) {

                    isXmlContext = "\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e" + isXmlContext;
                }
                */

                if (window.DOMParser) {//Firefox, Chrome, Opera, Safari
                    parser = new DOMParser();
                    mXmlDoc = parser.parseFromString(isXmlContext, "text/xml");
                }
                else {// Internet Explorer
                    mXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                    mXmlDoc.async = "false";
                    mXmlDoc.loadXML(isXmlContext);
                }
            }
            var rootNode = mXmlDoc.documentElement;
            //rootNode.childNodes[i]
            return rootNode;
            //#endregion 实现...
        }

        //根据节点属性名取得节点对象,属性名不区分大小写,找不对则返回null。
        this.GetXmlNodeAttributeByName = function (node, findAttributeName) {
            //#region 实现...
            if (node) {
                var attributeName = "";
                for (var i = 0 ; i < node.attributes.length; i++) {
                    attributeName = node.attributes[i].name.toLowerCase();

                    if (findAttributeName.toLowerCase() == attributeName) {
                        return node.attributes[i];
                    }
                }
            }
            return null;
            //#endregion 实现...
        };

        //读取节点的属性值,如果属性不存在则返回空串""。
        this.GetXmlNodeAttributeValue = function (node, attributeName) {
            //#region 实现...
            if (node) {
                var attribute = this.GetXmlNodeAttributeByName(node, attributeName);
                if (attribute) {//attribute.nodeType == 2
                    return attribute.value;  //attribute.nodeValue
                }
            }
            return "";
            //#endregion 实现...
        };

        // 根据子节点名取得节点的子节点对象,子节点名不区分大小写,找不对则返回null。
        this.GetXmlNodeChildNodeByName = function (node, childNodeName) {
            //#region 实现...
            if (node) {
                var son = undefined;
                var sonName = undefined;
                var childNodeValue = undefined;

                for (var i = 0 ; i < node.childNodes.length; i++) {
                    son = node.childNodes[i];
                    sonName = son.nodeName;
                    if (son.nodeType != 1 || sonName == undefined) {
                        continue;
                    }
                    sonName = sonName.toLowerCase();
                    if (sonName == childNodeName.toLowerCase()) {
                        return son;
                    }
                }
            }
            return null;
            //#endregion 实现...
        };

        //读取节点子节点的值,如果不存在则返回空串""。
        this.GetXmlNodeChildNodeValue = function (node, childNodeName) {
            //#region 实现...
            if (node) {
                var childNode = this.GetXmlNodeChildNodeByName(node, childNodeName);

                if (childNode) {
                    return childNode.textContent;
                }
            }
            return "";
            //#endregion 实现...
        };

        // 选择匹配Xml文档中指定节点标记名的第一个节点。注意节点名区分大小写的。
        this.SelectSingleNodeByNodeName = function (xmlFileName, nodeName) {
            if (node) {
                GoldPrinter.Throw.Msg("实现ing");
            }
            return undefined;
        };

        // 在Xml文档中查找匹配节点标记名指定属性值的第一个节点。注意节点名属性及值都是区分大小写的。
        this.SelectSingleNodeByAttribute = function (xmlFileName, nodeName, attributeName, attributeValue) {
            if (node) {
                GoldPrinter.Throw.Msg("实现ing");
            }
            return undefined;
        };

        /*只为与C#保持一致,在js意义不大。C#中从预定义的颜色名如Red、Gold或十六进制的颜色如#0000FF或以逗号分隔的三色值,如255,255,255 创建一个System.Drawing.Color结构。*/
        this.GetColorFrom = function (color) {
            if (color) {
                var arr = color.split(',');
                if (arr.length >= 2) {
                    if (color.toLowerCase().indexOf("rgb") < 0) {
                        return "rgb(" + color + ")";
                    }
                }
                return color;
            }
            return "black";
        };

    }

    //继承于接口IXmlParser
    jXmlParser.XmlParserBase.prototype = new jXmlParser.IXmlParser();
     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值