[英]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.