代码语言:javascript复制
public static class XmlHelper
{
public static string toSafe(this string strValue)
{
if(!string.IsNullOrEmpty(strValue))
{
strValue = strValue.Replace("%", "%");
strValue = strValue.Replace("#", "#");
strValue = strValue.Replace("$", "$");
}
return strValue;
}
public static string toNormal(this string strValue)
{
if(!string.IsNullOrEmpty(strValue))
{
strValue = strValue.Replace("#", "#");
strValue = strValue.Replace("$", "$");
strValue = strValue.Replace("%", "%");
}
return strValue;
}
/// <summary>
/// 创建xml文件,如果该文件存在则取消动作
/// </summary>
/// <param name="myXmlPath">创建的路径</param>
/// <param name="rootName">根节点名称</param>
public static void CreateXml(string myXmlPath, string rootName)
{
if (!File.Exists(myXmlPath))
{
XDocument xdoc = new XDocument(
new XElement(rootName)
);
xdoc.Save(myXmlPath);
}
}
/// <summary>
/// 搜索一个带路径的节点
/// </summary>
/// <param name="myXmlPath">xml路径</param>
/// <param name="path">
/// 描述:节点路径
/// 类型:string
/// 表示:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
/// </param>
/// <returns></returns>
public static IEnumerable<XElement> Search(string myXmlPath, string path)
{
XElement rootNode = XElement.Load(myXmlPath);
var query = Search(rootNode, path);
return query;
}
/// <summary>
/// 搜索一个带路径和目标属性值的节点
/// </summary>
/// <param name="myXmlPath">xml路径</param>
/// <param name="path">
/// 描述:节点路径
/// 类型:string
/// 表示:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
/// </param>
/// <param name="attrNameValue">
/// 描述:查找的属性值,允许传入多个属性and查找
/// 类型:string
/// 格式:id#123$name#1 或 id#123
/// </param>
/// <returns></returns>
public static IEnumerable<XElement> Search(string myXmlPath, string path, string attrNameValue)
{
XElement rootNode = XElement.Load(myXmlPath);
var query = Search(rootNode, path, attrNameValue);
return query;
}
/// <summary>
///
/// </summary>
/// <param name="rootNode">传入的根节点</param>
/// <param name="path">xml文件路径</param>
/// <param name="attrNameValue">
/// 描述:用于查找的属性。可以为多个。
/// 格式:id#1$name#王大锤
/// </param>
/// <returns></returns>
private static IEnumerable<XElement> Search(XElement rootNode, string path, string attrNameValue)
{
try
{
var query = Search(rootNode, path);
string[] attrInfo = attrNameValue.Split('$');
//下面使用表达式树查询多个属性
IQueryable<XElement> queryableData = query.AsQueryable<XElement>();
ParameterExpression pe = Expression.Parameter(typeof(XElement), "node");
Expression expression = Expression.Constant(true);
foreach (var item in attrInfo)
{
string[] attrValueName = item.Split('#');
Expression attrName = Expression.Constant((XName)attrValueName[0]);
var method = typeof(XElement).GetMethod("Attribute");
Expression left = Expression.Call(pe,
method, attrName);//Attribute(attrName)
Expression leftValue = Expression.Property(left, typeof(XAttribute).GetProperty("Value"));//Attribute(attrName).Value
Expression right = Expression.Constant(attrValueName[1]);
Expression e1 = Expression.Equal(leftValue, right);//Attribute(attrName).Value == attrValue
expression = Expression.And(e1, expression);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<XElement, bool>>(expression, new ParameterExpression[] { pe })
);
query = query.Where(o => o.Attribute(attrInfo[0]).Value == attrInfo[1]);
IQueryable<XElement> results = queryableData.Provider.CreateQuery<XElement>(whereCallExpression);
return results;
}
catch
{
return new List<XElement>();
}
}
private static IEnumerable<XElement> Search(XElement rootNode, string path)
{
string[] paths = path.Split('#');
IEnumerable<XElement> query = rootNode.Elements().Where(x => x.Name == paths[0]);
for (int i = 1; i < paths.Length; i )
{
string keyword = paths[i];
query = query.Elements().Where(p => p.Name == keyword);
}
return query;
}
private readonly static object _AddNodeLock = new object();
/// <summary>
/// 增加一个节点,找到要增加的父节点,然后添加
/// </summary>
/// <param name="myXmlPath">xml文档路径</param>
/// <param name="path">父节点路径</param>
/// <param name="newNode">
/// 描述:新节点
/// 类型:string
/// 格式:nodeName$attr1=attrValue1#attr2=attrValue2$nodeValue
/// </param>
public static void AddNode(string myXmlPath, string path, string newNode)
{
lock(_AddNodeLock)
{
string[] mainNode = newNode.Split('$');
XElement tempNode = new XElement(mainNode[0]);
if (mainNode[1] != "")
{
string[] attrNameValue = mainNode[1].Split('#');
//下面增加属性
foreach (var item in attrNameValue)
{
string[] tempAttr = item.Split('=');
tempNode.SetAttributeValue(tempAttr[0], tempAttr[1]);
}
}
tempNode.SetValue(mainNode[2]);
XElement rootNode = XElement.Load(myXmlPath);
XElement findNode;
if (string.IsNullOrEmpty(path))
{
findNode = rootNode;
}
else
{
findNode = Search(rootNode, path).FirstOrDefault();
}
findNode.Add(tempNode);
rootNode.Save(myXmlPath);
}
}
/// <summary>
/// 删除一个带路径的节点
/// </summary>
/// <param name="myXmlPath">文件路径</param>
/// <param name="path">
/// 描述:文件节点路径
/// 类型:string
/// 格式:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
/// </param>
public static void RemoveNode(string myXmlPath, string path)
{
XElement rootNode = XElement.Load(myXmlPath);
var targetNodes = Search(rootNode, path);
targetNodes.Remove();
rootNode.Save(myXmlPath);
}
/// <summary>
/// 通过属性和层次路径删除节点
/// </summary>
/// <param name="myXmlPath">xml物理路径</param>
/// <param name="path">节点层次路径</param>
/// <param name="attrNameValue">
/// 描述:查找的属性值,允许传入多个属性and查找
/// 类型:string
/// 格式:id#123$name#1 或 id#123
/// </param>
public static void RemoveNode(string myXmlPath, string path, string attrNameValue)
{
if (string.IsNullOrEmpty(attrNameValue))
{
RemoveNode(myXmlPath, path);
return;
}
XElement rootNode = XElement.Load(myXmlPath);
var targetNodes = Search(rootNode, path, attrNameValue);
targetNodes.Remove();
rootNode.Save(myXmlPath);
}
/// <summary>
/// 通过层次和属性查找节点,并修改节点信息
/// </summary>
/// <param name="myXmlPath">xml物理路径</param>
/// <param name="path">节点的层次路径</param>
/// <param name="attrNameValue">
/// 描述:查找的属性值,允许传入多个属性and查找
/// 类型:string
/// 格式:id#123$name#1 或 id#123
/// </param>
/// <param name="newAttrNameValue">
/// 描述:新增添的属性值,允许一次添加多个属性
/// 类型:string
/// 格式:id#123$name#1 或 id#123
/// </param>
/// <param name="newValue"></param>
public static void Modifiy(string myXmlPath, string path, string attrNameValue, string newAttrNameValue, string newValue)
{
XElement rootNode = XElement.Load(myXmlPath);
var targetNode = Search(rootNode, path, attrNameValue).FirstOrDefault();
if (targetNode == null)
{
return;
}
if (!string.IsNullOrEmpty(newAttrNameValue))
{
string[] allAttr = newAttrNameValue.Split('$');
foreach (var item in allAttr)
{
string[] attr = item.Split('#');
targetNode.SetAttributeValue(attr[0], attr[1]);
if (attr[1] == "null")
{
targetNode.Attribute(attr[0]).Remove();
}
}
}
if (!string.IsNullOrEmpty(newValue))
{
if (newValue == "null")
{
targetNode.SetValue("");
}
else
{
targetNode.SetValue(newValue);
}
}
rootNode.Save(myXmlPath);
}
}