[英]Join 3 XML document at specific attribute and get single XML document using LINQ in C#
[英]Inserting new XML Data at specific Point in document C# Using LINQ
大家好,我整天都在寻找可以使用LINQ将数据添加到现有XML文档中的方法。 我似乎只能找到如何创建新元素以及如何将它们添加到文件末尾。 我正在尝试创建一个应用程序,该应用程序允许我添加FTP帐户并从Filezilla Ftp客户端更新现有帐户,而无需手动执行。 这是XML文档。
<FileZillaServer>
<Settings>
<Item name="Admin port" type="numeric">14147</Item>
</Settings>
<Groups />
<Users>
<User Name="ServerManager">
<Option Name="Pass">6</Option>
<Option Name="Group">
</Option>
<Option Name="Bypass server userlimit">0</Option>
<Option Name="User Limit">0</Option>
<Option Name="IP Limit">0</Option>
<Option Name="Enabled">1</Option>
<Option Name="Comments">
</Option>
<Option Name="ForceSsl">0</Option>
<IpFilter>
<Disallowed />
<Allowed />
</IpFilter>
<Permissions>
<Permission Dir="C:\Dayz Server Manager">
<Option Name="FileRead">1</Option>
<Option Name="FileWrite">1</Option>
<Option Name="FileDelete">1</Option>
<Option Name="FileAppend">1</Option>
<Option Name="DirCreate">1</Option>
<Option Name="DirDelete">1</Option>
<Option Name="DirList">1</Option>
<Option Name="DirSubdirs">1</Option>
<Option Name="IsHome">1</Option>
<Option Name="AutoCreate">0</Option>
</Permission>
<Permission />
</Permissions>
<SpeedLimits DlType="0" DlLimit="10" ServerDlLimitBypass="0" UlType="0" UlLimit="10" ServerUlLimitBypass="0">
<Download />
<Upload />
</SpeedLimits>
</User>
</Users>
</FileZillaServer>
到目前为止,我已经能够弄清楚如何使用LINQ查询进入文档的正确位置,但是还不确定如何添加到文档中。 任何帮助将不胜感激。 以下是我用来使我处于正确位置的查询。
var InsHere = from name in doc.Descendants("Users")
where name.Element("User").Attribute("Name").Value == "ServerManager"
select name.Element("User").Element("Permissions")
.Element("Permission").Attribute("Dir").Value;
因此,在这种情况下,我需要为特定用户添加另一个目录,该目录将不断变化。 很多情况下,我需要创建一个全新的用户。 预先感谢您的任何帮助。
好吧,在查看示例和给出的答案之后,我想我已经越来越近了。 但是,我仍然收到“父项丢失”异常或“对象引用”错误。 这是我用来尝试插入的以下代码。
try
{
XDocument doc = XDocument.Load("C:/users/vildez/desktop/test.xml");
XElement test = new XElement("TEST", "this is data");
var InsertPoint = from user in doc.Descendants("Users")
where user.Element("User").Attribute("Name").Value == "ServerManager"
select user.Element("User").Element("Permissions").Element("Permission").Name;
foreach (var v in InsertPoint)
{
XElement Perm = doc.Element(v.ToString());
Perm.AddAfterSelf(test);
}
doc.Save("C:/users/vildez/desktop/123.xml");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Application.Exit();
}
如果您尝试添加新的权限元素,则可以使用AddAfterSelf(请参阅: http : //msdn.microsoft.com/query/dev11.query? appId=Dev11IDEF1&l=EN-US&k=k(System.Xml.Linq.XNode .AddAfterSelf); k(AddAfterSelf); k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5); k(DevLang-csharp)&rd = true )。 您的Linq必须进行更改以删除.Attribute(“ Dir”)。Value
如果尝试添加第二个“ Dir”属性,则不能这样做。 XML属性应该是唯一的。
-回应评论-
“ ...我不是在尝试创建另一个属性,而是创建另一个元素,它将基本上克隆之前的那个属性以及只是不同的目录路径等”
听起来您想添加具有修改后的目录属性的其他Permission元素。
var InsHere = from name in doc.Descendants("Users")
where name.Element("User").Attribute("Name").Value == "ServerManager"
select name.Element("User").Element("Permissions").Element("Permission");
var newElement = new XElement(InsHere); // this clones the found Permission element
newElement.Attribute("Dir").Value = "the new directory path to add";
InsHere.AddAfterSelf(newElement);
看看是否满足您的要求。
只需系统地考虑一下即可。 将xml元素添加到文档中的特定xml元素需要做什么?
那么,在本文档中这意味着什么呢?
Permissions
元素。 public XElement AddDirectoryPermissionForUser(XDocument doc, string userName, string dir)
{
// I prefer using xpath queries over full linq queries
var xpath = String.Format("//User[@Name='{0}']", userName);
var user = doc.XPathSelectElement(xpath); // 1
if (user != null)
{
var permission = CreatePermissionForDir(dir); // 2
user.Element("Permissions").Add(permission); // 3
return permission;
}
return null;
}
我不确定您到底在做什么,但这应该为您提供一个良好的起点。
您可以在任何其他XElement 之前,之后添加XElement。
基于您的查询添加/调整选项的演示:
string userName = "ServerManager";
string directory = "some directory";
string optionName = "FileRead";
int optionSetting = 1;
XElement doc = XElement.Load("C:/users/vildez/desktop/test.xml");
XElement user = doc.Descendants("User")
.FirstOrDefault(user =>
user.Attribute("Name").Value == userName);
// Add user if it doesn't exist
if (user == null)
{
XElement users = doc.Element("Users");
if (users == null)
doc.Add(users = new XElement("Users"));
users.Add(user = new XElement("User",
new XAttribute("Name", userName)));
}
XElement permission = user.Descendants("Permission")
.FirstOrDefault(perm =>
perm.Attribute("Dir").Value == directory);
// Add permission if it doesn't exist
if (permission == null)
{
XElement permissions = user.Element("Permissions");
if (permissions == null)
user.Add(permissions = new XElement("Permissions"));
permissions.Add(permission = new XElement("Permission",
new XAttribute("Dir", directory)));
}
XElement option = permission.Elements("Option")
.FirstOrDefault(op => op.Attribute("Name").Value == optionName);
// Add option if it doesn't exist
if (option == null)
permission.Add(option = new XElement("Option",
new XAttribute("Name", optionName)));
option.Value = optionSetting.ToString();
我不太清楚您要完成的工作,但是以上内容将为Permission添加一个新的Option,并且如果Permission不存在,请添加它。
我只对根节点使用XElement(而不是XDocument),所以我将其更改为那个(XElement)。 上面的代码可能与使用XDocument一样工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.