[英]Reading XML data in C#
我一直在嘗試如何用XML制作數據庫。 我已成功寫入數據,如下所示:
<Employees>
<Worker>
<ID>1</ID>
<FirstName>Ilan</FirstName>
<LastName>Berlinbluv</LastName>
<Salary>5000</Salary>
</Worker>
</Employees>
問題是當我嘗試使用以下代碼閱讀時:
string writePath = Environment.ExpandEnvironmentVariables("%USERPROFILE%") + @"\Desktop";
string writeFile = writePath + @"\Employees.xml";
using (XmlReader read = XmlReader.Create(writeFile))
{
while (read.Read())
{
if (read.IsStartElement())
{
Console.WriteLine("DEBUG: read.Name = {0}", read.Name);
Console.WriteLine("DEBUG: read.Value = {0}", read.Value);
switch (read.Name)
{
case "Employees":
Console.WriteLine("Start <Employees> master element");
break;
case "Employee":
Console.WriteLine("Start <Employee> element");
break;
case "Worker":
Console.WriteLine("Start <Worker> element");
break;
case "ID":
Console.WriteLine("Start reading <ID> element");
Console.WriteLine("Contains: " + read.Value.Trim());
break;
case "FirstName":
Console.WriteLine("Start reading <FirstName> element");
Console.WriteLine("Contains: " + read.Value.Trim());
break;
case "LastName":
Console.WriteLine("Start reading <LastName> element");
Console.WriteLine("Contains: " + read.Value.Trim());
break;
case "Salary":
Console.WriteLine("Start reading <Salary> element");
Console.WriteLine("Contains: " + read.Value.Trim());
break;
}
}
Console.ReadKey();
}
}
每當它說Start reading <Salary> element
然后Contains:
,它都不會正確讀取值,它不會顯示任何值,但應該有一個值:5000。這是語法錯誤,在我需要的地方像:
<ID>
1
</ID>
我一直在做dotnetperls教程,但無濟於事。
不要嘗試編寫代碼來讀取XML文檔。 請使用內置的XML序列化程序。 http://msdn.microsoft.com/en-us/library/fa420a9y.aspx
You can read XML like:
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("\\foldername\\" + "filename.xml"));
XmlNode node = doc.SelectSingleNode("//Employees//Worker/Salary");
Response.Write(node.InnerText.ToString());
This way, you can get 5000 as Salary.
您可以使用XSD工具來使用序列化程序。 首先創建一個XML模式,然后從XML模式創建一個類。 然后,您可以將XML直接讀取到對象:
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <exception cref="InvalidOperationException"></exception>
/// <returns></returns>
public static T Deserialize<T>(XmlNode xml)
{
// Assuming xml is an XML document containing a serialized object.
XmlNodeReader reader = new XmlNodeReader(xml);
// When we get the xml, it is usually a sub element that can have a different name, than the type name. Therefore look for the name
XmlSerializer ser = new XmlSerializer(typeof(T));
object obj = ser.Deserialize(reader);
// Then you just need to cast obj into whatever type it is eg:
return (T)obj;
}
/// <summary>
/// Serializes without removing namespace and using the specified encoding
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="encoding"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException">When the object can not be serialized to xml</exception>
public static XmlDocument Serialize<T>(T obj, Encoding encoding)
{
XmlSerializer ser = GetSerializer(obj.GetType());
using (MemoryStream stream = new MemoryStream())
using (XmlTextWriter writer = new XmlTextWriter(stream, encoding))
{
ser.Serialize(writer, obj);
XmlDocument doc = new XmlDocument();
writer.Flush();
stream.Position = 0;
doc.Load(stream);
return doc;
}
}
您可能需要在創建類之前編輯XML模式,以確保類型正確。
獲得對XML文件的特定節點的訪問權限的最簡單方法是使用LINQ。
string writePath = Environment.ExpandEnvironmentVariables("%USERPROFILE%") + @"\Desktop";
string writeFile = writePath + @"\Employees.xml";
XDocument xmlDocument = XDocument.Load(writeFile)
然后,如果您想讀取Worker元素中的所有元素
var queryResult = from x in xmlDocument.Root.Element("Worker").Elements() select x;
foreach (var item in queryResult)
{
Console.WriteLine(item.Value);
}
或者,如果您要分別處理所有Worker元素,則只需將查詢結果轉換為列表
var queryResult = (from x in xmlDocument.Root.Element("Worker").Elements() select x).ToList();
Console.WriteLine("Start reading <ID> element");
Console.WriteLine("Contains: " + queryResult[0]);
Console.WriteLine("Start reading <FirstName> element");
Console.WriteLine("Contains: " + queryResult[1]);
Console.WriteLine("Start reading <LastName> element");
Console.WriteLine("Contains: " + queryResult[2]);
Console.WriteLine("Start reading <Salary> element");
Console.WriteLine("Contains: " + queryResult[3]);
我發現在業務對象之間進行序列化時,使用XML總是更容易。
[Serializable]
public class Employees
{
private List<Worker> _Workers;
[XmlArray]
public List<Worker> Workers
{
get { return _Workers; }
set { _Workers = value; }
}
}
[Serializable]
public class Worker
{
public Int32 ID { get; set; }
public String FirstName { get; set; }
// etc.
public void SerializeToXML(string outputFolderLocation)
{
try
{
if (!outputFolderLocation.EndsWith('\\'))
{
outputFolderLocation += "\\";
}
//Create our own namespaces for the output
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
//Add an empty namespace and empty value
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(Worker));
string outpath = outputFolderLocation + "FileName-" + DateTime.Now.ToBinary().ToString() + ".xml";
XmlTextWriter textWriter = new XmlTextWriter(outpath, Encoding.GetEncoding("ISO-8859-1"));
serializer.Serialize(textWriter, this, ns);
textWriter.Close();
}
catch (Exception ex)
{
throw new Exception("Error serializing to XML", ex);
}
}
}
您還可以通過設置XML屬性值而不是節點來整理XML。 為此,您可以將屬性更改為:
[XmlAttribute("ID-Value")]
public Int32 ID { get; set; }
// would serialise like this <worker ID-Value="1"></worker>
您需要使用read.InnerText而不是read.Value。
了解了所有這些工作原理后,建議您使用內置的XML處理功能。 您將省去很多麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.