import {PlatformEnum} from '../PlatformEnum';
import {RuntimeUtil} from '../RuntimeUtil';
import {Attributes} from '../lang/Attributes';
import {Fatal} from '../lang/Fatal';
import {StringBuffer} from '../lang/StringBuffer';
import {StringUtil} from '../lang/StringUtil';
import {ClassUtil} from '../reflect/ClassUtil';
import {MethodUtil} from '../reflect/MethodUtil';
import {Node} from './Node';
import {NodeTypeEnum} from './NodeTypeEnum';
import {XmlDocument} from './XmlDocument';
//==========================================================
// 配置工具类。
//
// @reference
// @author maocy
// @version 150104
//==========================================================
export class XmlUtil {
public static httpActiveX = false;
public static httpVendor = null;
public static domActiveX = false;
public static domVendor = null;
//==========================================================
// 构造配置工具类。
//==========================================================
public static initialize() {
// 检查平台
if (RuntimeUtil.platformCd == PlatformEnum.NodeJs) {
return;
}
//...........................................................
var hWindow: any = window;
var hDocument = hWindow.document;
var error = null;
//...........................................................
// 获得请求方式
if (hWindow.ActiveXObject && !hWindow.XMLHttpRequest) {
var vs = ["MSXml2.XmlHTTP", "Microsoft.XmlHTTP", "MSXml.XmlHTTP", "MSXml3.XmlHTTP"];
var c = vs.length;
for (var n = 0; n < c; n++) {
var v = vs[n];
try {
var hActiveX = new ActiveXObject(v);
this.httpActiveX = true;
this.httpVendor = v;
break;
} catch (e) {
error = e;
}
}
} else if (hWindow.XMLHttpRequest) {
try {
var hRequest = new XMLHttpRequest();
this.httpActiveX = false;
} catch (e) {
error = e;
}
} else {
// console.log('Unknown http vendor.');
}
//...........................................................
// 获得文档方式
if (hWindow.ActiveXObject || !hWindow.DOMParser) {
var vs = ["MSXml2.DOMDocument", "Microsoft.XmlDOM", "MSXml.DOMDocument", "MSXml3.XmlDOM"];
var c = vs.length;
for (var n = 0; n < c; n++) {
var v = vs[n];
try {
var hActiveX = new ActiveXObject(v);
this.domActiveX = true;
this.domVendor = v;
break;
} catch (e) {
error = e;
}
}
} else if (hWindow.DOMParser && hDocument && hDocument.implementation && hDocument.implementation.createDocument) {
try {
var hActiveX = hDocument.implementation.createDocument('', '', null);
this.domActiveX = false;
} catch (e) {
error = e;
}
} else {
alert('Unknown dom vendor.');
}
}
//==========================================================
// 创建一个配置链接。
//
// @method
// @return 配置链接
//==========================================================
public static createConnection() {
var hConnection = null;
if (this.httpActiveX) {
hConnection = new ActiveXObject(this.httpVendor);
} else {
hConnection = new XMLHttpRequest();
}
// Error
if (!hConnection) {
alert('Create xml connection failure. (message=' + hConnection + ')');
}
return hConnection;
}
//==========================================================
// 创建一个配置文档。
//
// @method
// @return 配置链接
//==========================================================
public static createDocument() {
var hDocument = null;
if (this.domActiveX) {
hDocument = new ActiveXObject(this.domVendor);
} else {
hDocument = document.implementation.createDocument('', '', null);
}
// Error
if (!hDocument) {
alert('Create xml document failure. (message=' + hDocument + ')');
}
return hDocument;
}
//==========================================================
// 判断是否是一个节点(TNode)类型
//
// @method
// @param n:Node:TNode 节点对象
// @return Boolean 返回Boolean类型
//==========================================================
public static isNode(n) {
return ClassUtil.isName(n, 'TNode');
}
//==========================================================
// 格式化文本。
//
// @method
// @param s:string:String 字符串
// @return String 替换后的字符串
//==========================================================
public static formatText(s) {
if (s != null) {
s = s.replace(/\\n/g, '\n');
}
return s;
}
//==========================================================
// 替换字符串中的转义字符。
//
// @method
// @param s:string:FString 字符串
// @param v:value:String 内容
// @return FString 字符串
//==========================================================
public static buildText(s, v) {
if (v != null) {
v = v.toString();
var c = v.length;
for (var i = 0; i < c; i++) {
var ch = v.charAt(i);
switch (ch) {
case '<':
s.append('<');
break;
case '>':
s.append('>');
break;
case '&':
s.append('&');
break;
case '\'':
s.append(''');
break;
case '"':
s.append('"');
break;
case '\r':
continue;
case '\n':
s.append('\\n');
break;
default:
s.append(ch);
}
}
}
return s;
}
//==========================================================
// 遍历构建XML节点树
//
// @method
// @param pd:document:TXmlDocument JS系统中的XML文件
// @param pn:node:TXmlNode 父节点
// @param pe:element:XmlElement 页面元素
// @see RXml.fromText
// @see TXmlDoc.create
//==========================================================
public static buildNode(pd, pn, pe) {
// 建立属性集合
var xas = null;
var eas = pe.attributes;
if (eas) {
var eac = eas.length;
if (eac > 0) {
xas = new Attributes();
for (var n = 0; n < eac; n++) {
var ea = eas[n];
if (ea.nodeName) {
xas.set(ea.nodeName, this.formatText(ea.value));
}
}
}
}
// 建立文本
var xt = new StringBuffer();
xt.append(pe.value);
var ecs = pe.childNodes
if (ecs) {
var ecc = ecs.length;
for (var n = 0; n < ecc; n++) {
var en = ecs[n];
var ect = en.nodeType;
if (ect == NodeTypeEnum.Text) {
xt.append(en.nodeValue);
} else if (ect == NodeTypeEnum.Data) {
xt.append(en.data);
}
}
}
// 创建节点
var xc = pd.create(pe.nodeName, xas, StringUtil.trim(xt.toString()));
if (pn) {
pn.push(xc);
} else {
pd._root = xc;
}
// 创建子节点集合
if (ecs) {
var cc = ecs.length;
for (var n = 0; n < cc; n++) {
if (ecs[n].nodeType == NodeTypeEnum.Node) {
this.buildNode(pd, xc, ecs[n]);
}
}
}
}
//==========================================================
// 根据页面中的配置节点对象构建配置节点。
//
// @method
// @param p:document:document 嵌在页面中的配置节点
// @return TXmlNode 配置节点
//==========================================================
public static makeNode(p) {
var o: any = this;
if (p.documentElement) {
var d = new XmlDocument();
o.buildNode(d, null, p.documentElement);
return d.root();
} else if (p.tagName == 'SCRIPT') {
var s = p.textContent;
if (!s) {
s = p.text;
}
if (s) {
var d = new XmlDocument();
var xd = o.makeString(s)
o.buildNode(d, null, xd.documentElement);
return d.root();
}
}
return null;
}
//==========================================================
// 根据页面中的配置节点对象构建配置文档。
//
// @method
// @param p:document:document 嵌在页面中的配置节点
// @return TXmlDocument 配置文档
//==========================================================
public static makeDocument(p) {
var d = new XmlDocument();
if (p.documentElement) {
this.buildNode(d, null, p.documentElement);
}
return d;
}
//==========================================================
// 解包节点字符串。
//
// @method
// @param s:string:String 打包字符串
// @param n:node:TNode 节点对象
// @return TNode 节点对象
//==========================================================
public static unpack(s, n) {
var o = this;
if (StringUtil.isEmpty(s)) {
return null;
}
if (!n) {
n = new Node();
}
var np = new Attributes();
np.unpack(s);
n.name = np.get('name');
n.value = np.get('value');
if (np.contains('attributes')) {
n.attributes().unpack(np.get('attributes'));
}
if (np.contains('nodes')) {
//var ns = new sk.common.FStrings();
//ns.unpack(np.get('nodes'));
//for (var i = 0; i < ns.count; i++) {
// o.unpack(ns.get(i), n.create());
//}
}
return n;
}
//==========================================================
// 存储对象。
//
// @method
// @param xconfig:TXmlNode 配置节点
// @param item:Object 对象
//==========================================================
public static saveObject(xconfig, tag, item) {
var o = this;
for (var name in item) {
var value = item[name];
if (value != null) {
var xtag = xconfig.create(tag);
xtag.set('name', name);
var typeName = typeof (value);
switch (typeName) {
case 'boolean':
case 'number':
case 'date':
case 'string':
xtag.setValue(value);
break;
case 'function':
xtag.setValue(MethodUtil.shortName(value));
break;
case 'object':
o.saveObject(xtag, 'Property', value);
break;
default:
throw new Fatal(this, 'Invalid object.');
}
}
}
}
// //==========================================================
// // 格式化文本。
// //
// // @method
// // @param s:string:String 字符串
// // @return String 替换后的字符串
// //==========================================================
// public static _formatText(s) {
// if (s != null) {
// s = s.replace(/\\n/g, '\n');
// }
// return s;
// }
// //==========================================================
// // 替换字符串中的转义字符。
// //
// // @method
// // @param s:string:FString 字符串
// // @param v:value:String 内容
// // @return FString 字符串
// //==========================================================
// public static buildText(s, v) {
// if (v != null) {
// v = v.toString();
// var c = v.length;
// for (var i = 0; i < c; i++) {
// var ch = v.charAt(i);
// switch (ch) {
// case '<':
// s.append('<');
// break;
// case '>':
// s.append('>');
// break;
// case '&':
// s.append('&');
// break;
// case '\'':
// s.append(''');
// break;
// case '"':
// s.append('"');
// break;
// case '\r':
// continue;
// case '\n':
// s.append('\\n');
// break;
// default:
// s.append(ch);
// }
// }
// }
// return s;
// }
// //==========================================================
// // 遍历构建XML节点树
// //
// // @method
// // @param pd:document:TXmlDocument JS系统中的XML文件
// // @param pn:node:TXmlNode 父节点
// // @param pe:element:XmlElement 页面元素
// // @see RXmlUtil.fromText
// // @see TXmlDoc.create
// //==========================================================
// public static buildNode(pd, pn, pe) {
// // 建立属性集合
// var xas = null;
// var eas = pe.attributes;
// if (eas) {
// var eac = eas.length;
// if (eac > 0) {
// xas = new FAttributes();
// for (var n = 0; n < eac; n++) {
// var ea = eas[n];
// if (ea.nodeName) {
// xas.set(ea.nodeName, this.formatText(ea.value));
// }
// }
// }
// }
// // 建立文本
// var xt = new FString();
// xt.append(pe.value);
// var ecs = pe.childNodes
// if (ecs) {
// var ecc = ecs.length;
// for (var n = 0; n < ecc; n++) {
// var en = ecs[n];
// var ect = en.nodeType;
// if (ect == MO.ENodeType.Text) {
// xt.append(en.nodeValue);
// } else if (ect == MO.ENodeType.Data) {
// xt.append(en.data);
// }
// }
// }
// // 创建节点
// var xc = pd.create(pe.nodeName, xas, RString.trim(xt.toString()));
// if (pn) {
// pn.push(xc);
// } else {
// pd._root = xc;
// }
// // 创建子节点集合
// if (ecs) {
// var cc = ecs.length;
// for (var n = 0; n < cc; n++) {
// if (ecs[n].nodeType == ENodeType.Node) {
// this.buildNode(pd, xc, ecs[n]);
// }
// }
// }
// }
//==========================================================
// 加载一个配置字符串。
//
// @method
// @param n:Node:TNode 节点对象
// @return Boolean 返回Boolean类型
//==========================================================
public static makeString(source: string): any {
var xconfig = null;
// 判断浏览器的类型
if (this.domActiveX) {
xconfig = new ActiveXObject(this.domVendor);
xconfig.async = false;
xconfig.loadXML(source);
} else {
var p = new DOMParser();
xconfig = p.parseFromString(source, 'text/xml');
}
return xconfig;
}
// //==========================================================
// // 根据页面中的配置节点对象构建配置节点。
// //
// // @method
// // @param p:document:document 嵌在页面中的配置节点
// // @return TXmlNode 配置节点
// //==========================================================
// public static makeNode(p) {
// var o = this;
// if (p.documentElement) {
// var d = new MO.TXmlDocument();
// o.buildNode(d, null, p.documentElement);
// return d.root();
// } else if (p.tagName == 'SCRIPT') {
// var s = p.textContent;
// if (!s) {
// s = p.text;
// }
// if (s) {
// var d = new MO.TXmlDocument();
// var xd = o.makeString(s)
// o.buildNode(d, null, xd.documentElement);
// return d.root();
// }
// }
// return null;
// }
// //==========================================================
// // 根据页面中的配置节点对象构建配置文档。
// //
// // @method
// // @param p:document:document 嵌在页面中的配置节点
// // @return TXmlDocument 配置文档
// //==========================================================
// public static makeDocument(p) {
// var d = new MO.TXmlDocument();
// if (p.documentElement) {
// this.buildNode(d, null, p.documentElement);
// }
// return d;
// }
// //==========================================================
// // 解包节点字符串。
// //
// // @method
// // @param s:string:String 打包字符串
// // @param n:node:TNode 节点对象
// // @return TNode 节点对象
// //==========================================================
// public static unpack(s, n) {
// var this = this;
// if (MO.Lang.String.isEmpty(s)) {
// return null;
// }
// if (!n) {
// n = new MO.TNode();
// }
// var np = new MO.TAttributes();
// np.unpack(s);
// n.name = np.get('name');
// n.value = np.get('value');
// if (np.contains('attributes')) {
// n.attributes().unpack(np.get('attributes'));
// }
// if (np.contains('nodes')) {
// var ns = new MO.TStrings();
// ns.unpack(np.get('nodes'));
// for (var i = 0; i < ns.count; i++) {
// this.unpack(ns.get(i), n.create());
// }
// }
// return n;
// }
}
XmlUtil.initialize();