using System;
using System.IO;
using System.Collections;
using BP.DA;
using System.Data;
using BP.Sys;
using BP.En;
namespace BP.Sys.XML
{
///
/// XmlEn 的摘要说明。
///
abstract public class XmlEn
{
#region 获取值
private Row _row = null;
public Row Row
{
get
{
if (this._row == null)
this._row = new Row();
// throw new Exception("xmlEn 没有被实例化。");
return this._row;
}
set
{
this._row = value;
}
}
///
/// 获取一个对象
///
///
///
public Object GetValByKey(string attrKey)
{
if (this._row == null)
return null;
return this.Row.GetValByKey(attrKey);
}
public int GetValIntByKey(string key)
{
try
{
return int.Parse(this.GetValByKey(key).ToString().Trim());
}
catch
{
throw new Exception("key=" + key + "不能向int 类型转换。val=" + this.GetValByKey(key));
}
}
public decimal GetValDecimalByKey(string key)
{
return (decimal)this.GetValByKey(key);
}
///
/// 获取一个对象
///
///
///
public string GetValStringByKey(string attrKey)
{
if (this._row == null)
return "";
try
{
return this.Row.GetValByKey(attrKey) as string;
}
catch (Exception ex)
{
throw new Exception(" @XMLEN Error Attr=[" + attrKey + "], ClassName= " + this.ToString() + " , File =" + this.GetNewEntities.File + " , Error = " + ex.Message);
}
}
public string GetValStringHtmlByKey(string attrKey)
{
return this.GetValStringByKey(attrKey).Replace("\n", "
").Replace(" ", " ");
}
///
/// 获取一个对象
///
///
///
public bool GetValBoolByKey(string key)
{
string val = this.GetValStringByKey(key);
if (DataType.IsNullOrEmpty(val))
return false;
if (val == "1" || val.ToUpper() == "TRUE")
return true;
else
return false;
}
public void SetVal(string k, object val)
{
this.Row.SetValByKey(k, val);
}
#endregion 获取值
#region 构造函数
///
/// 构造函数
///
public XmlEn()
{
}
public int RetrieveByPK(string key, string val)
{
XmlEns ens = Cache.GetObj(this.GetNewEntities.ToString(), Depositary.Application) as XmlEns;
if (ens == null)
{
ens = this.GetNewEntities;
ens.RetrieveAll();
//Cache.SetConn(this.GetNewEntities.ToString(), Depositary.Application) as XmlEns;
}
int i = 0;
foreach (XmlEn en in ens)
{
if (en.GetValStringByKey(key).Equals(val))
{
this.Row = en.Row;
i++;
break;
}
}
if (i == 1)
return 1;
if (i > 1)
{
// SystemConfig.DoClearCache();
throw new Exception("@XML=[" + this.ToString() + "]中PK=" + val + "不唯一...");
}
return 0;
}
public int Retrieve(string key, string val, string key1,string val1)
{
XmlEns ens = Cache.GetObj(this.GetNewEntities.ToString(), Depositary.Application) as XmlEns;
if (ens == null)
{
ens = this.GetNewEntities;
ens.RetrieveAll();
}
int i = 0;
foreach (XmlEn en in ens)
{
if (en.GetValStringByKey(key) == val && en.GetValStringByKey(key1)==val1 )
{
this.Row = en.Row;
i++;
}
}
if (i == 1)
return 1;
return 0;
}
#endregion 构造函数
#region 需要子类实现的方法
public abstract XmlEns GetNewEntities { get; }
#endregion 需要子类实现的方法
}
abstract public class XmlEnNoName:XmlEn
{
public string No
{
get
{
return this.GetValStringByKey("No");
}
set
{
this.SetVal("No", value);
}
}
public string Name
{
get
{
return this.GetValStringByKey("Name");
}
set
{
this.SetVal("Name", value);
}
}
public XmlEnNoName()
{
}
public XmlEnNoName(string no)
{
int i= this.RetrieveByPK("No", no);
if (i == 0)
throw new Exception("@没有查询到 No ="+no+" XML数据.");
}
}
///
/// XmlEn 的摘要说明。
///
abstract public class XmlEns:System.Collections.CollectionBase
{
public int LoadXmlFile(string file)
{
return LoadXmlFile(file, this.TableName);
}
public int LoadXmlFile(string file, string table)
{
DataSet ds = new DataSet();
ds.ReadXml(file);
DataTable dt = ds.Tables[table];
foreach (DataRow dr in dt.Rows)
{
XmlEn en = this.GetNewEntity;
en.Row = new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
}
return dt.Rows.Count;
}
public bool Contine(string key, string val)
{
foreach (XmlEn en in this)
{
if (en.GetValStringByKey(key) == val)
return true;
}
return false;
}
#region 构造
///
/// 构造
///
public XmlEns()
{
}
#endregion 构造
#region 查询方法
public string Tname
{
get
{
string tname = this.File.Replace(".TXT", "").Replace(".txt", "");
tname = tname.Substring(tname.LastIndexOf("/") + 1) + this.TableName + "_X";
return tname;
}
}
private DataTable GetTableTxts(FileInfo[] fis)
{
DataTable cdt = Cache.GetObj(this.Tname, Depositary.Application) as DataTable;
if (cdt != null)
return cdt;
DataTable dt = new DataTable(this.TableName);
foreach (FileInfo fi in fis)
{
dt = GetTableTxt(dt, fi);
}
Cache.AddObj(this.Tname,
Depositary.Application, dt);
return dt;
}
private DataTable GetTableTxt()
{
DataTable cdt = Cache.GetObj(this.Tname, Depositary.Application) as DataTable;
if (cdt != null)
return cdt;
DataTable dt = new DataTable(this.TableName);
FileInfo fi = new FileInfo(this.File);
dt = GetTableTxt(dt, fi);
Cache.AddObj(this.Tname,
Depositary.Application, dt);
return dt;
}
private DataTable GetTableTxt(DataTable dt,FileInfo file)
{
StreamReader sr = new StreamReader(file.FullName, System.Text.ASCIIEncoding.GetEncoding("GB2312"));
Hashtable ht = new Hashtable();
string key = "";
string val = "";
while (true)
{
if (sr.EndOfStream)
break;
string lin = sr.ReadLine();
if (lin == "" || lin == null)
continue;
if (lin.IndexOf("*") == 0)
{
/* 遇到注释文件 */
continue;
}
if (lin.IndexOf("=") == 0 || sr.EndOfStream)
{
/* 约定的行记录, 开始以 = 开始就认为是一个新的记录。 */
// 处理表结构。
foreach (string ojbkey in ht.Keys)
{
if (dt.Columns.Contains(ojbkey) == false)
{
dt.Columns.Add(new DataColumn(ojbkey, typeof(string)));
}
}
DataRow dr = dt.NewRow();
foreach (string ojbkey in ht.Keys)
{
dr[ojbkey] = ht[ojbkey];
}
if (ht.Keys.Count > 1)
dt.Rows.Add(dr);
ht.Clear(); // clear hashtable.
if (sr.EndOfStream)
break;
continue;
}
int idx = lin.IndexOf("=");
if (idx == -1)
{
throw new Exception(this.File + "@不符合规则 key =val 的规则。");
}
key = lin.Substring(0, idx);
if (key == "")
continue;
val = lin.Substring(idx + 1);
ht.Add(key, val);
}
return dt;
}
public DataTable GetTable()
{
DataTable cdt = Cache.GetObj(this.Tname, Depositary.Application) as DataTable;
if (cdt != null)
return cdt;
if (this.File.ToLower().IndexOf(".txt") > 0)
{
return this.GetTableTxt();
}
if (this.File.ToLower().IndexOf(".xml") > 0)
{
DataSet ds1 = new DataSet();
ds1.ReadXml(this.File);
DataTable mdt = ds1.Tables[this.TableName];
if (mdt == null)
mdt = new DataTable();
Cache.AddObj(this.Tname,
Depositary.Application, mdt);
return ds1.Tables[this.TableName];
}
/* 说明这个是目录 */
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(this.File);
if (di.Exists == false)
throw new Exception("文件不存在:" + this.File);
FileInfo[] fis = di.GetFiles("*.xml");
if (fis.Length == 0)
{
fis = di.GetFiles("*.txt");
return this.GetTableTxts(fis);
}
DataTable dt = new DataTable(this.TableName);
if (fis.Length == 0)
return dt;
DataTable tempDT = new DataTable();
foreach (FileInfo fi in fis)
{
DataSet ds = new DataSet("myds");
try
{
ds.ReadXml(this.File + fi.Name);
}
catch (Exception ex)
{
throw new Exception("读取文件:" + fi.Name + "错误。Exception=" + ex.Message);
}
try
{
//ds.
if (dt.Columns.Count == 0)
{
/* 如果表还是空的,没有任何结构。*/
try
{
dt = ds.Tables[this.TableName];
}
catch (Exception ex)
{
throw new Exception("可能是没有在" + fi.Name + "文件中找到表:" + this.TableName + " exception=" + ex.Message);
}
tempDT = dt.Clone();
continue;
}
DataTable mydt = ds.Tables[this.TableName];
if (mydt == null)
throw new Exception("无此表:" + this.TableName);
if (mydt.Rows.Count == 0)
continue;
foreach (DataRow mydr in mydt.Rows)
{
//dt.ImportRow(mydr);
DataRow dr = dt.NewRow();
foreach (DataColumn dc in tempDT.Columns)
{
//string "sd".Clone();
if (dc.ColumnName.IndexOf("_Id") != -1)
continue;
try
{
object obj = mydr[dc.ColumnName];
dr[dc.ColumnName] = obj;
}
catch (Exception ex)
{
throw new Exception("xml 配置错误,多个文件中的属性不对称。" + ex.Message);
}
}
dt.Rows.Add(dr);
}
}
catch (Exception ex)
{
throw new Exception("获取数据出现错误:fileName=" + fi.Name + " clasName=" + this.ToString() + " MoreInfo=" + ex.Message);
}
}
Cache.AddObj(this.Tname,
Depositary.Application,
dt);
return dt;
}
public virtual int RetrieveAllFromDBSource()
{
Cache.RemoveObj(this.Tname);
return this.RetrieveAll();
}
///
/// 装载XML
///
public virtual int RetrieveAll()
{
this.Clear(); // 清所有的信息。
XmlEns ens = Cache.GetObj(this.ToString(), Depositary.Application) as XmlEns;
if (ens != null)
{
foreach (XmlEn en in ens)
this.Add(en);
return ens.Count;
}
// 从内存中找。
DataTable dt = this.GetTable();
foreach (DataRow dr in dt.Rows)
{
XmlEn en = this.GetNewEntity;
en.Row = new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
}
Cache.AddObj(this.ToString(), Depositary.Application, this);
return dt.Rows.Count;
}
public void FullEnToCache(string pk)
{
this.RetrieveAll();
XmlEn myen = this.GetNewEntity;
foreach (XmlEn en in this)
{
Cache.AddObj(myen.ToString() + en.GetValByKey(pk),
Depositary.Application, en);
}
}
public int RetrieveByLength(string key, int len )
{
this.Clear(); //清所有的信息
DataTable dt = this.GetTable();
int i = 0;
foreach (DataRow dr in dt.Rows)
{
if (dr[key].ToString().Length == len )
{
XmlEn en = this.GetNewEntity;
en.Row = new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
i++;
}
}
return i;
}
public int Retrieve(string key, object val)
{
return RetrieveBy(key,val);
}
public int Retrieve(string key, object val, string key1, string val1)
{
this.Clear(); //清所有的信息
DataTable dt = this.GetTable();
if (dt == null)
throw new Exception("@错误:类" + this.GetNewEntity.ToString() + " File= " + this.File + " Table=" + this.TableName + " ,没有取到数据。");
int i = 0;
try
{
foreach (DataRow dr in dt.Rows)
{
if (dr[key].ToString() == val.ToString() && dr[key1].ToString() == val1)
{
XmlEn en = this.GetNewEntity;
en.Row = new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
i++;
}
}
}
catch(Exception ex)
{
throw new Exception("@装载错误:file="+this.File+" xml:"+this.ToString()+"Err:"+ex.Message);
}
return i;
}
///
/// 按照键值查询
///
/// 要查询的健
/// 值
/// 返回查询的个数
public int RetrieveBy(string key, object val)
{
if (val == null)
return 0;
this.Clear(); //清所有的信息
DataTable dt = this.GetTable();
if (dt == null)
throw new Exception("@错误:类"+this.GetNewEntity.ToString()+" File= "+this.File +" Table="+this.TableName +" ,没有取到数据。");
int i=0;
foreach(DataRow dr in dt.Rows)
{
if ( dr[key].ToString() == val.ToString())
{
XmlEn en =this.GetNewEntity;
en.Row= new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
i++;
}
}
return i;
}
public int RetrieveBy(string key, object val, string orderByAttr)
{
DataTable dt = this.GetTable() ;
DataView dv =new DataView(dt, orderByAttr,orderByAttr,DataViewRowState.Unchanged);
this.Clear(); //清所有的信息.
int i=0;
foreach(DataRow dr in dt.Rows)
{
if (dr[key].ToString() == val.ToString())
{
XmlEn en = this.GetNewEntity;
en.Row = new Row();
en.Row.LoadDataTable(dt, dr);
this.Add(en);
i++;
}
}
return i;
}
#endregion
#region 公共方法
public XmlEn Find(string key, object val)
{
foreach(XmlEn en in this)
{
if (en.GetValStringByKey(key)==val.ToString())
return en;
}
return null;
}
public bool ItIsExits(string key, object val)
{
foreach(XmlEn en in this)
{
if (en.GetValStringByKey(key)==val.ToString())
return true;
}
return false;
}
#endregion
#region 增加 便利访问
public XmlEn GetEnByKey(string key,string val)
{
foreach(XmlEn en in this)
{
if (en.GetValStringByKey(key) ==val)
return en;
}
return null;
}
///
/// 根据位置取得数据
///
public XmlEn this[int index]
{
get
{
return (XmlEn)this.InnerList[index];
}
}
///
/// 获取数据
///
public XmlEn this[string key, string val]
{
get
{
foreach(XmlEn en in this)
{
if (en.GetValStringByKey(key)==val)
return en;
}
throw new Exception("在["+this.TableName+","+this.File+","+this.ToString()+"]没有找到key="+key+", val="+val+"的实例。");
}
}
///
/// 增加一个xml en to Ens.
///
///
///
public virtual int Add(XmlEn entity)
{
return this.InnerList.Add(entity);
}
public virtual int Add(XmlEns ens)
{
if (ens == null)
return 0;
foreach (XmlEn en in ens)
{
this.InnerList.Add(en);
}
return ens.Count;
}
#endregion
#region 与 entities 接口
///
/// 把数据装入一个实例集合中(把xml数据装入物理表中)
///
/// 实体集合
public void FillXmlDataIntoEntities(Entities ens)
{
this.RetrieveAll(); // 查询出来全部的数据。
Entity en1 = ens.GetNewEntity;
string[] pks = en1.PKs;
foreach(XmlEn xmlen in this)
{
Entity en = ens.GetNewEntity;
foreach(string pk in pks)
{
object obj = xmlen.GetValByKey(pk);
en.SetValByKey(pk, obj);
}
try
{
en.RetrieveFromDBSources();
}
catch(Exception ex)
{
en.CheckPhysicsTable();
BP.DA.Log.DebugWriteError(ex.Message);
}
foreach(string s in xmlen.Row.Keys)
{
object obj = xmlen.GetValByKey(s);
if (obj==null )
continue;
if (obj.ToString()=="")
continue;
if (obj.ToString()=="None")
continue;
if (obj==DBNull.Value)
continue;
en.SetValByKey(s, obj);
}
en.Save();
}
}
public void FillXmlDataIntoEntities()
{
if (this.RefEns==null)
return ;
this.FillXmlDataIntoEntities(this.RefEns);
}
#endregion
#region 子类实现xml 信息的描述.
public abstract XmlEn GetNewEntity{get;}
///
/// 获取它所在的xml file 位置.
///
public abstract string File
{
get;
}
///
/// 物理表名称(可能一个xml文件中有n个Table.)
///
public abstract string TableName
{
get;
}
public abstract Entities RefEns
{
get;
}
#endregion
public DataTable ToDataTable()
{
DataTable dt = new DataTable(this.TableName);
if (this.Count == 0)
return dt;
XmlEn en = this[0] as XmlEn;
Row r = en.Row;
foreach (string key in r.Keys)
{
dt.Columns.Add(key, typeof(string));
}
foreach (XmlEn en1 in this)
{
DataRow dr = dt.NewRow();
foreach (string key in r.Keys)
{
dr[key] = en1.GetValStringByKey(key);
}
dt.Rows.Add(dr);
}
return dt;
}
}
}