-
一个用于读写XML文档的类
//writer:furenjun 2006.05.05
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
![](/Images/OutliningIndicators/None.gif)
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Text;
namespace MrfuReadAndWriteXmlFile
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// C_MrFuXmlManager 的摘要说明。
/// </summary>
public class C_MrFuXmlManager
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public C_MrFuXmlManager()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//
// TODO: 在此处添加构造函数逻辑
//
}
![](/Images/OutliningIndicators/InBlock.gif)
string myXmlFilePath=Application.StartupPath +@"\Users.xml";
string tempFilePath=Application.StartupPath +@"\Temp.xml";
public string GsXmlFilePath
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{return myXmlFilePath;}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{myXmlFilePath=value;}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
XmlDocument Operation#region XmlDocument Operation
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 创建xml文档
/// </summary>
/// <returns></returns>
public bool CreateMyXmlFile()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlTextWriter myTextWriter=new XmlTextWriter (this.GsXmlFilePath ,System.Text.Encoding.GetEncoding("GB2312") );
![](/Images/OutliningIndicators/InBlock.gif)
myTextWriter.Formatting =Formatting.Indented; //写入文本的缩进格式
myTextWriter.WriteStartDocument(true); //设置standalone="no" //当为(true)时 <?xml version="1.0" standalone="yes" ?>
//如果 XML 文档所需要的所有实体声明都包含在文档内,则有效值为 yes,或者如果需要外部 DTD,则为 no。如果 XML 声明中没有独立特性,该属性将返回 String.Empty。
myTextWriter.WriteDocType("mrfuDocType",null,null,null) ;
myTextWriter.WriteComment("System user info,warning : do not modify! "); //添加注释
//myTextWriter.WriteStartElement("mrfu");
//Write the namespace declaration.
//myTextWriter.WriteAttributeString("xmlns", "Users", null, "urn:UsersInfo");//为前面的element写属性
![](/Images/OutliningIndicators/InBlock.gif)
myTextWriter.WriteStartElement("mrfu","Users","urn:UsersInfo");
// myTextWriter.WriteElementString("Name","Fu") ;
// myTextWriter.WriteElementString("Pwd","renjun") ;
// myTextWriter.WriteElementString("DateOfLastlogin","06/08/1982") ;
myTextWriter.WriteEndElement() ;
// myTextWriter.WriteEndElement() ; //与上呼应,对应一个单元 区间.
//write the xml to file and close the myTextWriter
myTextWriter.Flush();
myTextWriter.Close();
//MessageBox.Show ("写入数据完毕.");
}
catch
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
return true;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 返回指定xml文档的数据集
/// </summary>
/// <returns></returns>
public DataSet GetMyXmlData()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataSet myDataSet=null;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
myDataSet= new DataSet();
![](/Images/OutliningIndicators/InBlock.gif)
myDataSet.ReadXml(this.GsXmlFilePath );
//MessageBox.Show (myDataSet.Tables[0].TableName.ToString () );
}
![](/Images/OutliningIndicators/InBlock.gif)
catch (Exception e1)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MessageBox.Show (e1.Message.ToString() ) ;
}
return myDataSet;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 插入数据至xml文档
/// </summary>
/// <param name="usInfo"></param>
/// <returns></returns>
public bool InsertDataInXmlFile(UserInfo usInfo)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlTextWriter TWriter=new XmlTextWriter(this.tempFilePath ,Encoding.GetEncoding("GB2312") );
TWriter.WriteStartDocument();
TWriter.WriteStartElement("mrfu","Users","urn:UsersInfo");
TWriter.WriteStartElement("User");
TWriter.WriteAttributeString("Id",usInfo.Id); //对前面的User写出具有指定的本地名称和值的属性
TWriter.WriteElementString("Name",usInfo.Name );
TWriter.WriteElementString("Pwd",usInfo.Pwd );
TWriter.WriteElementString("AreaFlag",usInfo.AreaFlag );
TWriter.WriteElementString("DateOfLastlogin",System.DateTime.Now.ToString() );
TWriter.WriteEndElement();
TWriter.WriteEndElement();
TWriter.WriteEndDocument();
![](/Images/OutliningIndicators/InBlock.gif)
TWriter.Flush();
TWriter.Close();
SaveUserInfo(this.tempFilePath );
}
catch
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
return true;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 保存数据至xml文档,与前面的插入方法结合使用.
/// </summary>
/// <param name="path"></param>
private void SaveUserInfo(string path)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
![](/Images/OutliningIndicators/InBlock.gif)
XmlDocument xdocImp=new XmlDocument();
xdocImp.Load(path);
![](/Images/OutliningIndicators/InBlock.gif)
XmlNodeList pNodes=xdocImp.SelectNodes("//User");
![](/Images/OutliningIndicators/InBlock.gif)
NameTable nametable=new NameTable();
XmlNamespaceManager nameMan=new XmlNamespaceManager(nametable);
nameMan.AddNamespace("mrfu","urn:UsersInfo");
![](/Images/OutliningIndicators/InBlock.gif)
foreach(XmlNode pNode in pNodes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlNode pNodeImp=xdoc.SelectSingleNode("//User[Name='"+pNode.ChildNodes.Item(0).InnerXml+"']");
if(pNodeImp==null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlNode importedNode=xdoc.ImportNode(pNode,true);
xdoc.SelectSingleNode("//mrfu:Users",nameMan).AppendChild(importedNode);
}
}
xdoc.Save(this.GsXmlFilePath );
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 按用户名查找用户的相关信息
/// </summary>
/// <param name="UserName"></param>
/// <returns></returns>
public UserInfo GetUserInfo(string UserName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
UserInfo usInfo=new UserInfo();
if(this.GetNumOfChild(UserName)<0 )
return usInfo;
![](/Images/OutliningIndicators/InBlock.gif)
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
XmlNodeList xList=xdoc.SelectNodes("//User[Name='"+UserName+"']");
foreach(XmlNode node in xList)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlNodeReader NReader=new XmlNodeReader(node);
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
while(NReader.Read())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(NReader.NodeType==XmlNodeType.Element)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(NReader.HasAttributes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
while(NReader.MoveToNextAttribute())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(NReader.Value!="urn:UsersInfo")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
usInfo.Id=NReader.Value;
}
}
}
}
if(NReader.Name=="Name")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
usInfo.Name =NReader.ReadString();
}
else if(NReader.Name=="Pwd")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
usInfo.Pwd =NReader.ReadString();
}
else if(NReader.Name=="AreaFlag")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
usInfo.AreaFlag =NReader.ReadString();
}
else if(NReader.Name=="DateOfLastlogin")
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
usInfo.DateOfLastlogin =NReader.ReadString();
}
![](/Images/OutliningIndicators/InBlock.gif)
}
}
catch(Exception err)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string errmsg="read xml file error \n"+err.ToString();
MessageBox.Show(errmsg);
}
finally
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(NReader!=null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
NReader.Close();
}
![](/Images/OutliningIndicators/InBlock.gif)
}
}
return usInfo;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 查找用户信息返回用户id的数据表
/// </summary>
/// <param name="UserName"></param>
/// <returns></returns>
public DataTable GetUserID(string UserName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataTable dt=new DataTable();
if(this.GetNumOfChild(UserName)<0 )
return dt;
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
XmlNodeList xList=xdoc.SelectNodes("//User[Name='"+UserName+"']");//可以根据实际需要更改它的查找范围.如SelectNodes("//User")
![](/Images/OutliningIndicators/InBlock.gif)
if (xList.Count> 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
CreateColumns(dt, xList[0]);
}
foreach(XmlNode node in xList)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataRow dr=dt.NewRow();
foreach(XmlAttribute attr in node.Attributes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
dr[attr.Name]=attr.Value;
}
dt.Rows.Add(dr);
}
return dt;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 创建列
/// </summary>
/// <param name="dt"></param>
/// <param name="node"></param>
protected static void CreateColumns(DataTable dt, XmlNode node)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach(XmlAttribute attr in node.Attributes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
dt.Columns.Add(new DataColumn(attr.Name));
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 查找当前用户结点的位置
/// </summary>
/// <param name="UserName"></param>
/// <returns></returns>
public int GetNumOfChild(string UserName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(!VerifyParameters())
return -1;
int i=-1;
ArrayList myArylist=new ArrayList();
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
XmlNodeList xList=xdoc.SelectNodes("//User");
![](/Images/OutliningIndicators/InBlock.gif)
int j=0;
int totalNum=xList.Count ;
bool find=false;
while((j<totalNum)&&(!find))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(xList[j].ChildNodes.Item(0).InnerText.Trim()==UserName.Trim() )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
i=j;
find=true;
}
j++;
}
return i;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 获取所有的用户名称
/// </summary>
/// <returns></returns>
public ArrayList GetTheNameOfAllUser( )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ArrayList myArylist=new ArrayList();
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
XmlNodeList xList=xdoc.SelectNodes("//User");
foreach(XmlNode xNode in xList)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
myArylist.Add(xNode.ChildNodes.Item(0).InnerText); //也可显示文档中的其它项,更改item(i)即可
}
return myArylist;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 更新指定用户的信息
/// </summary>
/// <param name="UserName"></param>
/// <param name="usInfo"></param>
/// <returns></returns>
public bool UpdateNotes(string UserName,UserInfo usInfo)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(this.GetNumOfChild(UserName)<0 )
return false;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
//创建一个文档片断来存储要替换的节点
XmlDocumentFragment xdocFrag=xdoc.CreateDocumentFragment();
//新节点的根节点
XmlElement newElement=xdoc.CreateElement("User");
XmlAttribute newID=xdoc.CreateAttribute("Id");
![](/Images/OutliningIndicators/InBlock.gif)
newID.Value=usInfo.Id ;
newElement.Attributes.SetNamedItem(newID);
![](/Images/OutliningIndicators/InBlock.gif)
XmlElement newName=xdoc.CreateElement("Name");
newName.InnerText=UserName;
newElement.AppendChild(newName);
![](/Images/OutliningIndicators/InBlock.gif)
XmlElement newPwd=xdoc.CreateElement("Pwd");
![](/Images/OutliningIndicators/InBlock.gif)
newPwd.InnerText=usInfo.Pwd ;
newElement.AppendChild(newPwd);
![](/Images/OutliningIndicators/InBlock.gif)
XmlElement newAreaFlag=xdoc.CreateElement("AreaFlag");
newAreaFlag.InnerText=usInfo.AreaFlag ;
newElement.AppendChild(newAreaFlag);
![](/Images/OutliningIndicators/InBlock.gif)
XmlElement newDateOfLastlogin=xdoc.CreateElement("DateOfLastlogin");
newDateOfLastlogin.InnerText=System.DateTime.Now.ToString() ;
newElement.AppendChild(newDateOfLastlogin);
![](/Images/OutliningIndicators/InBlock.gif)
//把新创建的节点加入文档片断
xdocFrag.AppendChild(newElement);
//确定要替换的节点作替换
NameTable nametable=new NameTable();
XmlNamespaceManager nameMan=new XmlNamespaceManager(nametable);
nameMan.AddNamespace("mrfu","urn:UsersInfo");
![](/Images/OutliningIndicators/InBlock.gif)
XmlElement xUsers=(XmlElement)xdoc.SelectSingleNode("//mrfu:Users",nameMan);
//找到该用户在文档中的结点序号(第几个孩子)
int i=GetNumOfChild(UserName);
if(i>=0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlElement xChild=(XmlElement)xUsers.ChildNodes[i];
xUsers.ReplaceChild(xdocFrag.FirstChild,xChild);
![](/Images/OutliningIndicators/InBlock.gif)
xdoc.Save(this.GsXmlFilePath );
}
else
return false;
![](/Images/OutliningIndicators/InBlock.gif)
}
catch
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
return true;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 删除指定用户的纪录
/// </summary>
/// <param name="UserName"></param>
/// <returns></returns>
public bool DeleteNotes(string UserName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument xdoc=new XmlDocument();
xdoc.Load(this.GsXmlFilePath );
![](/Images/OutliningIndicators/InBlock.gif)
NameTable nametable=new NameTable();
XmlNamespaceManager nameMan=new XmlNamespaceManager(nametable);
nameMan.AddNamespace("mrfu","urn:UsersInfo");
![](/Images/OutliningIndicators/InBlock.gif)
XmlNode rootnode=xdoc.SelectSingleNode("//mrfu:Users",nameMan);
XmlNode node=xdoc.SelectSingleNode("//User[Name='"+UserName+"']");
rootnode.RemoveChild(node);
xdoc.Save(this.GsXmlFilePath );
}
catch
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
![](/Images/OutliningIndicators/InBlock.gif)
}
return true;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 验证xml文档的有效性
/// </summary>
/// <returns></returns>
protected bool VerifyParameters()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bool bls=true;
if (!System.IO.File.Exists (this.GsXmlFilePath ))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bls=false;
throw(new Exception("xmlFile do not exists."));
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument doc=new XmlDocument();
doc.Load(this.GsXmlFilePath );
![](/Images/OutliningIndicators/InBlock.gif)
if (doc == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bls=false;
throw new Exception("doc cannot be null.");
}
if (doc.LastChild.GetType() == typeof(System.Xml.XmlDeclaration))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bls=false;
throw new Exception("XmlDocument requires at least the a root node");
}
}
return bls;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 获取当前根结点下的所有纪录值
/// </summary>
/// <returns></returns>
public DataTable GetDataFromXmlFile( )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
VerifyParameters();
![](/Images/OutliningIndicators/InBlock.gif)
XmlDocument doc=new XmlDocument();
doc.Load(this.GsXmlFilePath );
![](/Images/OutliningIndicators/InBlock.gif)
DataTable myTable=new DataTable();
XmlNodeList xList=doc.SelectNodes("//User");
![](/Images/OutliningIndicators/InBlock.gif)
// create data table
DataTable dt = new DataTable();
![](/Images/OutliningIndicators/InBlock.gif)
//读取它的元素名称
dt.Columns.Add(new DataColumn("Id"));
dt.Columns.Add(new DataColumn("Pwd"));
dt.Columns.Add(new DataColumn("AreaFlag"));
dt.Columns.Add(new DataColumn("DateOfLastlogin"));
![](/Images/OutliningIndicators/InBlock.gif)
//将各个元素对应的值一行一行写入表中
DataRow row = null;
foreach(XmlNode xNode in xList)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
row = dt.NewRow();
for(int j=0;j<4;j++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
row[j]=xNode.ChildNodes.Item(j).InnerText;
}
dt.Rows.Add( row );
}
dt.AcceptChanges();
return dt;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
public class UserInfo
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public string Id="";
public String Name="";
public string Pwd="";
public string AreaFlag="";
public string DateOfLastlogin="";
// public String Symbol="";
// public double Last;
// public DateTime Date;
// public double Change;
// public double Open;
// public double High;
// public double Low;
// public long Volume;
// public long MarketCap;
// public double PreviousClose;
// public double PreviousChange;
// public double Low52Week;
// public double High52Week;
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/None.gif)
-
相关阅读:
[转载]微软4月13日发布Silverlight 4
关于文件流Seek以及Read操作的一点不满
团队基础生成自动化流程之最佳实践(IV) 重写团队基础默认生成流程
谁是你的下一行CODE
团队基础生成自动化流程之最佳实践总论(II) – 程序集版本信息
微软Visual Studio 2010 第三集:幸福要敏捷
团队基础生成自动化流程之最佳实践(VI) 系统模块化条件编译
团队基础生成自动化流程之最佳实践(V) 使用Desktop Build
VS2010 "内存不足" 错误补丁
彩虹天堂
-
原文地址:https://www.cnblogs.com/furenjun/p/401567.html
Copyright © 2020-2023
润新知