在 xml c# 中计算特定节点的子节点



我有这个xml,我需要计算"用户"中的所有帐户。我尝试了几件事,但我得到的只是 xml 中所有帐户的值。我需要类似用户[1]/帐户的东西,并且仅获取该用户的帐户。

<UserList>
<User>
<Username>hello</Username>
<Pin>640</Pin>
<Accounts>
<AccountName>Dolar</AccountName>
<Balance>150</Balance>
<MaxWithdrawAmount>1200</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
<Accounts>
<AccountName>RON</AccountName>
<Balance>650</Balance>
<MaxWithdrawAmount>5000</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
</User>
<User>
<Username>Kevin</Username>
<Pin>1234</Pin>
<Accounts>
<AccountName>RON</AccountName>
<Balance>650</Balance>
<MaxWithdrawAmount>5000</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
<Accounts>
<AccountName>Lei</AccountName>
<Balance>950</Balance>
<MaxWithdrawAmount>1200</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
</User>
</UserList>

所以我的输出应该是:

"对于用户 1,您有 2 个帐户" "对于用户 x,您有 x 个帐户">

我喜欢使用带有linq的字典:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENANE = @"c:temptest.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENANE);
Dictionary<string, User> dict = doc.Descendants("User").Select(x => new User()
{
username = (string)x.Element("Username"),
pin = (int)x.Element("Pin"),
accounts = x.Elements("Accounts").ToList()
}).GroupBy(x => x.username, y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
foreach (var user in dict)
{
Console.WriteLine("User : {0}, Count = {1}", user.Key, user.Value.accounts.Count());
}
Console.ReadLine();

}
}
public class User
{
public string username { get; set; }
public int pin { get; set; }
public List<XElement> accounts { get; set; }
}
}

这是完成此操作的一种方法。
请阅读代码中的注释。

namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string XML_String = @"<UserList>
<User>
<Username>hello</Username>
<Pin>640</Pin>
<Accounts>
<AccountName>Dolar</AccountName>
<Balance>150</Balance>
<MaxWithdrawAmount>1200</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
<Accounts>
<AccountName>RON</AccountName>
<Balance>650</Balance>
<MaxWithdrawAmount>5000</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
</User>
<User>
<Username>Kevin</Username>
<Pin>1234</Pin>
<Accounts>
<AccountName>RON</AccountName>
<Balance>650</Balance>
<MaxWithdrawAmount>5000</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
<Accounts>
<AccountName>Lei</AccountName>
<Balance>950</Balance>
<MaxWithdrawAmount>1200</MaxWithdrawAmount>
<MaxDepositAmount>2000</MaxDepositAmount>
</Accounts>
</User>
</UserList>";
var users = GetUsers(XML_String);
// show in console
foreach (MyUser usr in users)
{
Console.WriteLine(usr);
}
Console.ReadLine();
}
private static List<MyUser> GetUsers(string xmlstring)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlstring);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("User");
// List to hold data
List<MyUser> MyUsersList = new List<MyUser>();
// Couter for the UserOrderNumber by his order in the document
int userOrderCounter = 0;
// Counter for number of accounts
int accountCounter = 0;
// itterate trough all <User> nodes
foreach (XmlNode node in nodes)
{
accountCounter = 0;
userOrderCounter++;

// create user object 
MyUser usr = new MyUser();
// Itterate trough all child nodes
for (int i = 0; i < node.ChildNodes.Count; i++)
{
if (node.ChildNodes[i].Name == "Username")
{
usr.Username = node.ChildNodes[i].InnerXml;
}
else if (node.ChildNodes[i].Name == "Pin")
{
usr.Pin = Convert.ToInt32(node.ChildNodes[i].InnerXml);
}
else if (node.ChildNodes[i].Name == "Accounts")
{
accountCounter++;
}
}
// Add the counters values
usr.UserOrderNumber = userOrderCounter;
usr.NumberOfAccountes = accountCounter;
// Add to list
MyUsersList.Add(usr);
}
return MyUsersList;
}
}
/// <summary>
/// class to hold users retrived from XML document
/// </summary>
class MyUser
{
public int UserOrderNumber { get; set; }
public string Username { get; set; }
public int Pin { get; set; }
public int NumberOfAccountes { get; set; }
public override string ToString()
{
return return "User " + UserOrderNumber.ToString() + " (Name " + Username + ")" + " Have " + NumberOfAccountes.ToString() + " Accounts";
}
}
}

输出:

用户 1(姓名 hello( 有 2 个帐户 用户 2(姓名 Kevin(有 2 个帐户

这可以使用 LINQ to XML (https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/linq-to-xml-overview( 来完成

您可以在下面找到一个狙击手:

var xmlDoc = XDocument.Parse(xml);
var userNumber = 0;
foreach (var user in xmlDoc.Element("UserList").Elements("User"))
{
userNumber++;
var accounts = user.Elements("Accounts").Count();
Console.WriteLine($"For User {userNumber}, you have {accounts} Accounts");
}

不要忘记添加所需的用途:

using System.Linq;
using System.Xml.Linq;

并添加对System.Xml.XDocument的引用.dll如果使用 .Net Core 或System.Xml.Linq.dll for .Net Framework

最新更新