C#,如何在匹配用户ID后从.xml文件中分配变量值? [英] C# ,how can i assign variables' values from a .xml file after i match the user id ?

查看:87
本文介绍了C#,如何在匹配用户ID后从.xml文件中分配变量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将所有用户信息都写在.xml文件中,我希望在匹配当前登录用户的ID后获取特定用户的所有值?



我尝试了什么:



  public   string  name; 
public static int id = WindowsFormsApplication5.Settings.Default.logedinuserID;
public int pin;
public string 地址;
public string phone;
public int checking_acc_num = 0 ;
public double checking_acc_Balance = 0 ;
public int saving_acc_num = 0 ;
public double saving_acc_Balance = 0 ;
private void LoadUSERS()
{
XmlDocument doc = < span class =code-keyword> new XmlDocument();
doc.Load( USERS.xml);

{
if (id!= 0
{
foreach ( doc.DocumentElement中的XmlNode节点
{
if (id == int .Parse(node [ PIN]。InnerText))
{
name = node.Attributes [ 0 ]值。
pin = int .Parse(node [ PIN]的innerText)。
checking_acc_num = int .Parse(node [ CheckingACC /货号]的innerText)。
checking_acc_Balance = int .Parse(node [ CheckingACC /平衡]的innerText)。
saving_acc_num = int .Parse(node [ SavingACC /货号]的innerText)。
saving_acc_Balance = int .Parse(node [ SavingACC /平衡]的innerText)。
address = node [ Address]。InnerText;
phone = node [ Phone]。InnerText;


}
}
}
}
}







这是我的Xml文件

<?xml version =1.0encoding =utf-8? > 
< root>
<用户名=Kamal Al Nasr>
< ID> 123456< / ID>
< PIN> 5100< / PIN>
< Name> Kamal Al Nasr< / Name>
< CheckingACC>
< Num> 52645852< / Num>
< Balance> 2500< / Balance>
< / CheckingACC>
< SavingACC>
< Num> 741852< / Num>
< Balance> 2000< / Balance>
< / SavingACC>
<地址> 3500 John Merritt Blvd,Nashville,TN 37209< / Address>
< Phone>(615)963-5848< / Phone>
< transactionHistory>
< t1>< / t1>
< t2>< / t2>
< t3>< / t3>
< t4>< / t4>
< t5>< / t5>
< t6>< / t6>
< t7>< / t7>
< t8>< / t8>
< t9>< / t9>
< t10>< / t10>
< t11>< / t11>
< t12>< / t12>
< t13>< / t13>
< t14>< / t14>
< t15>< / t15>
< t16>< / t16>
< t17>< / t17>
< t18>< / t18>
< t19>< / t19>
< t20>< / t20>
< / transactionHistory>
< / User>
<用户名=Mike Stewart>
< ID> 123457< / ID>
< PIN> 5110< / PIN>
< CheckingACC>
< Num> 8569745< / Num>
< Balance> 500< / Balance>
< / CheckingACC>
< SavingACC>
< Num> 741850< / Num>
< Balance> 3000< / Balance>
< / SavingACC>
<地址> 110 Nevada Ave.,Nashville,TN 37219< / Address>
< Phone>(615)963-5555< / Phone>
< transactionHistory>
< t1>< / t1>
< t2>< / t2>
< t3>< / t3>
< t4>< / t4>
< t5>< / t5>
< t6>< / t6>
< t7>< / t7>
< t8>< / t8>
< t9>< / t9>
< t10>< / t10>
< t11>< / t11>
< t12>< / t12>
< t13>< / t13>
< t14>< / t14>
< t15>< / t15>
< t16>< / t16>
< t17>< / t17>
< t18>< / t18>
< t19>< / t19>
< t20>< / t20>
< / transactionHistory>
< / User>
< User name =Adam Lin>
< ID> 123450< / ID>
< PIN> 5111< / PIN>
< CheckingACC>
< Num> 8565478< / Num>
< Balance> 4500< / Balance>
< / CheckingACC>
< SavingACC>
< Num> 741844< / Num>
< Balance> 2000< / Balance>
< / SavingACC>
< Address> 1120 Virginia Ave.,Nashville,TN 37210< / Address>
< Phone>(615)963-4444< / Phone>
< transactionHistory>
< t1>< / t1>
< t2>< / t2>
< t3>< / t3>
< t4>< / t4>
< t5>< / t5>
< t6>< / t6>
< t7>< / t7>
< t8>< / t8>
< t9>< / t9>
< t10>< / t10>
< t11>< / t11>
< t12>< / t12>
< t13>< / t13>
< t14>< / t14>
< t15>< / t15>
< t16>< / t16>
< t17>< / t17>
< t18>< / t18>
< t19>< / t19>
< t20>< / t20>
< / transactionHistory>
< / User>
< / root>

解决方案

您正在尝试使用.NET FCL提供的最差的XML API。这是我对这些API的简短概述:

  1. 使用 System.Xml.XmlDocument 类。它实现了DOM接口;如果文档的大小不是太大,这种方式是最简单和最好的。
    参见 http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx
  2. 使用类 System.Xml .XmlTextReader ;这是最快的阅读方式,特别是你需要跳过一些数据。
    参见 http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx
  3. 使用类 System.Xml.Linq .XDocument ;这是类似于 XmlDocument 的最合适的方式,支持LINQ to XML Programming。
    参见 http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx http://msdn.microsoft.com/en-us/library/bb387063.aspx




  4. 您的方法的另一个问题是您的解决方案完全是临时的,并且基于硬编码的立即常数,魔术字符串。这是不可能正确维护和难以开发的。这是一个很大的禁忌,众所周知的反模式

    https://en.wikipedia.org/wiki/Anti-pattern#Programming,

    魔术字符串 - 维基百科,免费的百科全书 [ ^ ],

    另见魔数(编程) - 维基百科,免费的百科全书 [ ^ ]。



    怎么办?我不确定您是否使用了来自未知来源的XML。如果您还要创建XML数据,最好使用序列化,而不是自己处理XML:

    Serialization - 维基百科,免费的百科全书 [ ^ ],

    编组(计算机科学) - 维基百科,免费百科全书 [ ^ ],
    .NET Framework中的序列化 [< a href =https://msdn.microsoft.com/en-us/library/7ay27kt9(v=vs.110).aspx\"target =_ blanktitle =New Window> ^ ],

    .NET中的对象序列化 [ ^ ]。



    最好,最稳健最容易使用的方法是进行序列化 Data Contract 。请参阅:

    使用数据合同 [ ^ ],

    DataContractSerializer类(System.Runtime.Serialization) [ ^ ]。



    另请参阅我过去的答案,其中我主张数据合同方法:

    如何将数据合同从C#/ WCF代码传递到托管C ++ [ ^ ],

    如何在表单应用程序中使用XML文件编写器和阅读器? [ ^ ],

    创建属性文件...... [ ^ ],

    反序列化列表< class object>导致objects属性失去对基类对象的引用 [ ^ ],

    如何为列表类实现ICloneable? [ ^ ]。



    -SA


谢尔盖的回答非常有用,因为它提供了大量有用的信息。我建议你仔细阅读这个答案。



简而言之:最好的选择是使用 Xml Serailization [ ^ ]。

为什么?因为xml序列化和反序列化提供了一种将对象/数据写入xml并将其再次读入对象/数据的方法。





To能够使用XML序列化/反序列化,你应该定义类 - 例如:

  public   class 用户
{
私有 int id = 0 ;
private int pin = 0 ;
private CheckingACC cacc = new CheckingACC();

public int ID
{
get { return id;}
set {id = value ;}
}

public < span class =code-keyword> int PIN
{
get {返回 pin;}
set {pin = value ;}
}

public CheckingACC CheckingACC
{
get { return cacc;}
set {cacc = 价值;}
}

}

public class CheckingA CC
{
private int n = 0 ;
private double bal = 0 0 ;

public CheckingACC()
{
// 默认构造函数
}

public CheckingACC( int _n, double _b)
{
n = _n;
bal = _b;
}

public int Num
{
get { return n;}
set {n = value ;}
}

public double 余额
{
获取 { return bal;}
set {bal = value ;}
}
}





以同样的方式定义其他类/属性/成员。



欲了解更多详情,请阅读以下文章:

XML序列化的示例 [ ^ ]

https ://support.microsoft.com/en-us/kb/815813 [ ^ ]

XML序列化和反序列化:第1部分 [ ^ ]

XML序列化和反序列化:第2部分 [ ^ ]

自定义类集合的完整示例ialization和反序列化 [ ^ ]





另一种方法是将XDocument类与自定义类一起使用 - 如下所示:

  int  id =  123456 ; 

XDocument xdoc = XDocument.Parse(xcontent);
用户u = xdoc.Descendants( 用户
.Where( x = > int )x.Element( ID)== id)
。选择(x = > new 用户{
ID = Convert.ToInt32(x.Element( ID)。值),
PIN = Convert.ToInt32(x.Element( PIN)。值),
CheckingACC = new CheckingACC {
Num = Convert.ToInt32( x.Element( CheckingACC)。元素( Num)。值),
余额= Convert.ToDouble(x.Element( CheckingACC)。元素( Balance)。价值)
}
})
.SingleOrDefault();
// u变量存储所有数据





如您所见,上面的linq查询返回自定义类(特定对象)。神奇的代码是: x =>新用户{...}





我差点忘了提到你可以退货匿名类型:

  var  query = xdoc.Descendants(  用户
。其中(x = > int )x.Element( ID) == id)
。选择(x = > new {
ID = x.Element( ID)。值,
PIN = x.Element( PIN)。值,
CheckingACC_Num = x.Element( CheckingACC)。元素( Num)。值,
CheckingACC_Balance = x.Element( CheckingACC)。元素( Balance)。价值
});





以上查询返回:

 ID PIN CheckingACC_Num CheckingACC_Balance 
123456 5100 52645852 2500





祝你好运!


I have all of the user information written in an .xml file and I would like to get all of the values for a particular user after I match the id of the user who is logged in currently ?

What I have tried:

public string name;
        public static int id = WindowsFormsApplication5.Settings.Default.logedinuserID;
        public int pin;
        public string address;
        public string phone;
        public int checking_acc_num=0;
        public double checking_acc_Balance=0;
        public int saving_acc_num=0;
        public double saving_acc_Balance = 0;
        private void LoadUSERS()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("USERS.xml");

            {
                if (id != 0)
                {
                    foreach (XmlNode node in doc.DocumentElement)
                    {
                        if (id == int.Parse(node["PIN"].InnerText))
                        {
                            name = node.Attributes[0].Value;
                            pin = int.Parse(node["PIN"].InnerText);
                            checking_acc_num = int.Parse(node["CheckingACC/Num"].InnerText);
                            checking_acc_Balance = int.Parse(node["CheckingACC/Balance"].InnerText);
                            saving_acc_num = int.Parse(node["SavingACC/Num"].InnerText);
                            saving_acc_Balance = int.Parse(node["SavingACC/Balance"].InnerText);
                            address = node["Address"].InnerText;
                            phone = node["Phone"].InnerText;


                        }
                    }
                }
            }
        }




This is My Xml File

<?xml version="1.0" encoding="utf-8" ?>
<root>
<User name ="Kamal Al Nasr">
    <ID>123456</ID>
    <PIN>5100</PIN>
    <Name>Kamal Al Nasr</Name>
    <CheckingACC>
      <Num>52645852</Num>
      <Balance>2500</Balance>
    </CheckingACC>
    <SavingACC>
      <Num>741852</Num>
      <Balance>2000</Balance>
    </SavingACC>
    <Address>3500 John Merritt Blvd, Nashville, TN 37209</Address>
    <Phone>(615) 963-5848</Phone>
    <transactionHistory>
      <t1></t1>
      <t2></t2>
      <t3></t3>
      <t4></t4>
      <t5></t5>
      <t6></t6>
      <t7></t7>
      <t8></t8>
      <t9></t9>
      <t10></t10>
      <t11></t11>
      <t12></t12>
      <t13></t13>
      <t14></t14>
      <t15></t15>
      <t16></t16>
      <t17></t17>
      <t18></t18>
      <t19></t19>
      <t20></t20>
    </transactionHistory>
  </User>
  <User name ="Mike Stewart">
    <ID>123457</ID>
    <PIN>5110</PIN>
    <CheckingACC>
      <Num>8569745</Num>
      <Balance>500</Balance>
    </CheckingACC>
    <SavingACC>
      <Num>741850</Num>
      <Balance>3000</Balance>
    </SavingACC>
    <Address>110 Nevada Ave., Nashville, TN 37219</Address>
    <Phone>(615) 963-5555</Phone>
    <transactionHistory>
      <t1></t1>
      <t2></t2>
      <t3></t3>
      <t4></t4>
      <t5></t5>
      <t6></t6>
      <t7></t7>
      <t8></t8>
      <t9></t9>
      <t10></t10>
      <t11></t11>
      <t12></t12>
      <t13></t13>
      <t14></t14>
      <t15></t15>
      <t16></t16>
      <t17></t17>
      <t18></t18>
      <t19></t19>
      <t20></t20>
    </transactionHistory>
  </User>
  <User name ="Adam Lin">
    <ID>123450</ID>
    <PIN>5111</PIN>
    <CheckingACC>
      <Num>8565478</Num>
      <Balance>4500</Balance>
    </CheckingACC>
    <SavingACC>
      <Num>741844</Num>
      <Balance>2000</Balance>
    </SavingACC>
    <Address>1120 Virginia Ave., Nashville, TN 37210</Address>
    <Phone>(615) 963-4444</Phone>
    <transactionHistory>
      <t1></t1>
      <t2></t2>
      <t3></t3>
      <t4></t4>
      <t5></t5>
      <t6></t6>
      <t7></t7>
      <t8></t8>
      <t9></t9>
      <t10></t10>
      <t11></t11>
      <t12></t12>
      <t13></t13>
      <t14></t14>
      <t15></t15>
      <t16></t16>
      <t17></t17>
      <t18></t18>
      <t19></t19>
      <t20></t20>
    </transactionHistory>
  </User>
 </root>

解决方案

You are trying to use perhaps the worst XML API offered by .NET FCL. This is my short overview of those API:

  1. Use System.Xml.XmlDocument class. It implements DOM interface; this way is the easiest and good enough if the size if the document is not too big.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx.
  2. Use the class System.Xml.XmlTextReader; this is the fastest way of reading, especially is you need to skip some data.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx.
  3. Use the class System.Xml.Linq.XDocument; this is the most adequate way similar to that of XmlDocument, supporting LINQ to XML Programming.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx, http://msdn.microsoft.com/en-us/library/bb387063.aspx.



Another problem of your approach is that your solution is totally ad-hoc and is based on hard-coded immediate constants, "magic strings". This is impossible to properly maintain and hard to develop. This is a big no-no, a well known anti-pattern:
https://en.wikipedia.org/wiki/Anti-pattern#Programming,
Magic string — Wikipedia, the free encyclopedia[^],
see also Magic number (programming) — Wikipedia, the free encyclopedia[^].

What to do? I'm not sure if you are using some XML from unknown source. If you also are to create the XML data, you should better use serialization, instead of dealing with XML by yourself:
Serialization — Wikipedia, the free encyclopedia[^],
Marshalling (computer science) — Wikipedia, the free encyclopedia[^],
Serialization in the .NET Framework[^],
Object Serialization in .NET[^].

The best, most robust and easiest to use way of doing serialization is Data Contract. Please see:
Using Data Contracts[^],
DataContractSerializer Class (System.Runtime.Serialization)[^].

See also my past answers where I advocate Data Contract approach:
how to pass a datacontract from a C#/WCF code to Managed C++[^],
How can I utilize XML File streamwriter and reader in my form application?[^],
Creating property files...[^],
deserializing list<class object> cause the objects property lose their reference to the objects of the base class[^],
How to implement ICloneable for a List Class?[^].

—SA


Sergey's answer is very useful, because it provides tons of useful information. I'd recommend to read that answer very carefully.

In a short: the best option for you is to use Xml Serailization[^].
Why? Because xml serialization and deserialization provides a way to write objects/data into xml and to read it again into objects/data.


To be able to use XML Serialization/Deserialization, you should define classes - for example:

public class User
{
	private int id = 0;
	private int pin = 0;
	private CheckingACC cacc = new CheckingACC();
	
	public int ID
	{
		get {return id;}
		set {id = value;}
	}

	public int PIN
	{
		get {return pin;}
		set {pin = value;}
	}
	
	public CheckingACC CheckingACC
	{
		get {return cacc;}
		set {cacc = value;}
	}

}

public class CheckingACC
{
	private int n=0;
	private double bal=0.0;

	public CheckingACC()
	{
		//default constructor
	}
	
	public CheckingACC(int _n, double _b)
	{
		n = _n;
		bal = _b;
	}

	public int Num
	{
		get {return n;}
		set {n = value;}
	}
	
	public double Balance
	{
		get {return bal;}
		set {bal = value;}
	}
}



In the same way you should define other classes/properties/members.

For further details, please read these articles:
Examples of XML Serialization[^]
https://support.microsoft.com/en-us/kb/815813[^]
XML Serialization and Deserialization: Part-1[^]
XML Serialization and Deserialization: Part-2[^]
A Complete Sample of Custom Class Collection Serialization and Deserialization[^]


Another way is to use XDocument class together with custom classes - as follow:

	int id = 123456;
	
XDocument xdoc = XDocument.Parse(xcontent);
User u =	xdoc.Descendants("User")
			.Where(x=>(int)x.Element("ID") == id)
			.Select(x=> new User{
				ID = Convert.ToInt32(x.Element("ID").Value),
				PIN = Convert.ToInt32(x.Element("PIN").Value),
				CheckingACC = new CheckingACC{
						Num = Convert.ToInt32(x.Element("CheckingACC").Element("Num").Value),
						Balance = Convert.ToDouble(x.Element("CheckingACC").Element("Balance").Value)
					}
				})
			.SingleOrDefault();
//u variable stores all data 



As you can see, above linq query returns custom class (specific object). The magic is in this peace of code: x=> new User{...}

[EDIT]
I almost forgot to mention that you can return anonymous type:

var query = xdoc.Descendants("User")
            .Where(x=>(int)x.Element("ID") == id)
            .Select(x=> new {
                ID = x.Element("ID").Value,
                PIN = x.Element("PIN").Value,
                CheckingACC_Num = x.Element("CheckingACC").Element("Num").Value,
                CheckingACC_Balance = x.Element("CheckingACC").Element("Balance").Value
                });



Above query returns:

ID     PIN  CheckingACC_Num CheckingACC_Balance
123456 5100 52645852        2500 



Good luck!


这篇关于C#,如何在匹配用户ID后从.xml文件中分配变量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆