Чтение данных из XML
Я планирую использовать XML для базы данных. Единственное, что мне удалось сделать, это прочитать весь XML-файл. Я хочу иметь возможность читать только некоторые данные, и я не знаю, как это сделать.
Вот простой XML
<Books>
<Book>
<Title>Animals</Title>
<Author>J. Anderson</Author>
</Book>
<Book>
<Title>Car</Title>
<Author>L. Sawer</Author>
</Book>
</Books>
Я заинтересован в приложении, где выход будет
Books:
Animals
Cars
Authors:
J. Anderson
L. Sawer
Я просто хочу узнать, как читать конкретные данные из XML, а не весь файл.
[Решено] Я использовал Linq to XML
4 ответа
Я не думаю, что вы можете "легально" загрузить только часть файла XML, так как тогда он будет поврежден (где-то будет отсутствующий закрывающий элемент).
Используя LINQ-to-XML, вы можете сделать var doc = XDocument.Load("yourfilepath")
, Оттуда просто вопрос запрашиваемых данных, скажем так:
var authors = doc.Root.Elements().Select( x => x.Element("Author") );
НТН.
РЕДАКТИРОВАТЬ:
Хорошо, просто чтобы сделать этот образец лучше, попробуйте это (с предложенным улучшением @JWL_):
using System;
using System.Xml.Linq;
namespace ConsoleApplication1 {
class Program {
static void Main( string[] args ) {
XDocument doc = XDocument.Load( "XMLFile1.xml" );
var authors = doc.Descendants( "Author" );
foreach ( var author in authors ) {
Console.WriteLine( author.Value );
}
Console.ReadLine();
}
}
}
Вам нужно будет отрегулировать путь в XDocument.Load()
указать на ваш файл XML, но остальное должно работать. Задайте вопросы о том, какие части вы не понимаете.
Согласно комментарию @Jon Skeet, вы должны использовать XmlReader, только если ваш файл очень большой. Вот как это использовать. Предполагая, что у вас есть класс Book
public class Book {
public string Title {get; set;}
public string Author {get; set;}
}
Вы можете читать XML-файл построчно с небольшим объемом памяти, например так:
public static class XmlHelper {
public static IEnumerable<Book> StreamBooks(string uri) {
using (XmlReader reader = XmlReader.Create(uri)) {
string title = null;
string author = null;
reader.MoveToContent();
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Book") {
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Title") {
title = reader.ReadString();
break;
}
}
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Author") {
author =reader.ReadString();
break;
}
}
yield return new Book() {Title = title, Author = author};
}
}
}
}
Пример использования:
string uri = @"c:\test.xml"; // your big XML file
foreach (var book in XmlHelper.StreamBooks(uri)) {
Console.WriteLine("Title, Author: {0}, {1}", book.Title, book.Author);
}
В качестве альтернативы вы можете использовать XPathNavigator:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XPathNavigator navigator = doc.CreateNavigator();
string books = GetStringValues("Books: ", navigator, "//Book/Title");
string authors = GetStringValues("Authors: ", navigator, "//Book/Author");
..
/// <summary>
/// Gets the string values.
/// </summary>
/// <param name="description">The description.</param>
/// <param name="navigator">The navigator.</param>
/// <param name="xpath">The xpath.</param>
/// <returns></returns>
private static string GetStringValues(string description,
XPathNavigator navigator, string xpath) {
StringBuilder sb = new StringBuilder();
sb.Append(description);
XPathNodeIterator bookNodesIterator = navigator.Select(xpath);
while (bookNodesIterator.MoveNext())
sb.Append(string.Format("{0} ", bookNodesIterator.Current.Value));
return sb.ToString();
}
Попробуйте метод GetElementsByTagName класса XMLDocument для чтения определенных данных или метод LoadXml для чтения всех данных в XML-документе.