我一直在寻找一段时间如何编写服务器上注册的每个播放器的详细信息列表,这样当人们登录时,他们的详细信息将从xml文件中加载,然后从他们注销的地方恢复。
我知道有很多教程,但我似乎无法做任何工作。我需要随机访问,并实时在硬盘上更新文件。当前代码(远离工作)显示了后面的格式,但我不理解xml的大多数概念,例如什么是属性/节点/元素?教程似乎想让你知道..
XMLFile = XDocument.Load(@"C:/users.xml");
var users = XMLFile.Descendants( "Users" );
int count = 0;
foreach ( var user in users )
{
count++;
userName[count] = user.ToString();
XElement element = (XMLFile.FirstNode as XElement);
userPass[count] = element.Value;
XAttribute attribute = (XMLFile.NextNode as XAttribute);
userLocation[count] = attribute.Value;
attribute = (XAttribute)XMLFile.NextNode;
userRotation[count] = attribute.Value;
}
这个想法是文件的格式是这样的(如xml ..)
Users
Aaron
password
vector3 of location
Quaternion of Rotation
SomeoneElse
hispassword
Vector3 of location
Quaternion of rotation
//and so on....
当客户端登录并通过网络发送时,将读取这些值 其他一切正常我只是无法获得任何读/写xml的方法,所以感谢您的帮助。
答案 0 :(得分:9)
首先,它不是有效的XML格式。我想你的意思是:
<Users>
<User>
<Username>...</Username>
<Password>...</Password>
<Location>...</Location>
<Rotation>..</Rotation>
</User>
</Users>
其次,当我看到你将每个用户值存储到单独的数组中时,为什么?只需添加一个User类,并定义一个Users集合,并阅读使用此代码:
XDocument xDoc = XDocument.Load(@"C:/users.xml");
List<User> users = (from u in xDoc.Descendants("User")
select new User {
Name = u.Element("Username").Value,
Password = u.Element("Password").Value,
Location = u.Element("Locations").Value,
Rotation = u.Element("Rotation").Value
}).ToList();
你问过&#34; what is an attribute/node/element
&#34;
我们假设我们有这个元素:
<User ID = "23">
<Username>User123</Username>
</User>
在这个特定元素中:
ID
是 Xml属性 User
和Username
是 Xml元素 User
是Username
User
是元素节点,"User123"
是文本节点强>等... 更新:写入XML
如果你有这个xml结构,你可以简单地追加这样的新值(或者创建一个新的xml):
我假设您有一个名为users
XElement xmlElement = new XElement("Users",
from user in users
select new XElement("User",
new XElement("Username", user.Username),
new XElement("Password", user.Password),
new XElement("Location", user.Location),
new XElement("Rotation", user.Rotation)));
xmlElement.Save("Users.xml");
更新:验证用户
string userName = textBox1.Text;
string password = textBox2.Text;
XDocument xDoc = XDocument.Load(@"C:/users.xml");
var userControl = (from u in xDoc.Descendants("User")
where u.Element("Username").Value == userName
&& u.Element("Password").Value == password
select u).Any();
if(userControl)
{
// validated...
} else {
// User doesn't exist or password wrong
}
答案 1 :(得分:3)
首先,您可以考虑这两种xml文档格式:
这个使用属性来存储您的数据:
<Users>
<User UserName="User1" Pass="Pass1" Location="Location1" Rotation="Rotaition1" />
<User UserName="User2" Pass="Pass2" Location="Location2" Rotation="Rotaition2" />
</Users>
并且这个使用元素来存储您的数据:
<Users>
<User>
<UserName>User1</UserName>
<Pass>Pass1</Pass>
<Location>Location1</Location>
<Rotation>Rotation1</Rotation>
</User>
<User>
<UserName>User2</UserName>
<Pass>Pass2</Pass>
<Location>Location2</Location>
<Rotation>Rotation2</Rotation>
</User>
</Users>
用于创建第一个结构的示例代码:
XDocument xDocument = new XDocument();
XElement rootElement = new XElement("Users");
rootElement.Add(new XElement("User", new XAttribute("UserName", "User1"), new XAttribute("Pass", "Pass1"), new XAttribute("Location", "Location1"), new XAttribute("Rotation", "Rotaition1")));
rootElement.Add(new XElement("User", new XAttribute("UserName", "User2"), new XAttribute("Pass", "Pass2"), new XAttribute("Location", "Location2"), new XAttribute("Rotation", "Rotaition2")));
xDocument.Add(rootElement);
读取第一个结构的示例代码:
var xElement = xDocument.Descendants("User").Single(element => element.Attribute("UserName").Value == "User1");
用于创建第二个结构的示例代码:
XDocument xDocument = new XDocument();
XElement rootElement = new XElement("Users");
XElement userElement = new XElement("User");
userElement.Add(new XElement("UserName", "User1"));
userElement.Add(new XElement("Pass", "Pass1"));
userElement.Add(new XElement("Location", "Location1"));
userElement.Add(new XElement("Rotation", "Rotation1"));
rootElement.Add(userElement);
userElement = new XElement("User");
userElement.Add(new XElement("UserName", "User2"));
userElement.Add(new XElement("Pass", "Pass2"));
userElement.Add(new XElement("Location", "Location2"));
userElement.Add(new XElement("Rotation", "Rotation2"));
rootElement.Add(userElement);
xDocument.Add(rootElement);
最后,用于读取第二个结构的示例代码:
var xElement = xDocument.Descendants("User").Single(element => element.Element("UserName").Value == "User1");
您可以使用以下示例保存并加载xml文档:
xDocument.Save("Your xml file path"); // using Save() instance method
XDocument xDocument = XDocument.Load("Your xml file path"); // using Load() static method
根据您的要求,易用性以及格式良好的xml文档的最佳实践决定是选择第一个结构还是第二个结构。在这种情况下,我更喜欢第一个结构。有关格式良好的xml文档的进一步阅读,请参阅此 codeproject 文章:Well-Formed XML
请注意,上面的代码只是创建这两种xml文档的一些示例。在您的情况下,您只需要遍历users
集合并根据每个user
对象在循环中创建xml元素。
您还询问了xml的基本概念。 @ Selman22之前的回答快速而正确,但有关详细信息,请参阅以下参考文献:
答案 2 :(得分:0)
使用XML序列化程序将您的用户数组(或用户对象并使用多个文件)序列化为XML。 http://msdn.microsoft.com/en-us/library/182eeyhh(v=vs.110).aspx
写一个文件(来自MSDN)
MySerializableClass myObject = new MySerializableClass();
// Insert code to set properties and fields of the object.
XmlSerializer mySerializer = new
XmlSerializer(typeof(MySerializableClass));
// To write to a file, create a StreamWriter object.
using (StreamWriter myWriter = new StreamWriter("myFileName.xml"))
{
mySerializer.Serialize(myWriter, myObject);
}
从对象(来自MSDN)读取
MySerializableClass myObject;
// Construct an instance of the XmlSerializer with the type
// of object that is being deserialized.
XmlSerializer mySerializer =
new XmlSerializer(typeof(MySerializableClass));
// To read the file, create a FileStream.
using (FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open))
{
// Call the Deserialize method and cast to the object type.
myObject = (MySerializableClass)
mySerializer.Deserialize(myFileStream)
}
另外,“实时”写入磁盘非常昂贵,您可能需要考虑限制光盘访问。如果您的用户有“保存”选项,那么您可以先写入光盘,或者使用某种计时器进行刻录。
就随机访问而言,应该在内存中完成(不在文件中)。基本上你的流程是:用户登录 - &gt;将文件中的用户数据读入内存 - &gt;用户做的东西 - &gt;更新内存中的对象 - &gt;用户保存或“自动保存” - &gt;将对象写入磁盘。