Чтение данных из 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 для XML
Ответы
Ответ 1
Я не думаю, что вы можете "юридически" загружать только часть XML файла, так как тогда он будет искажен (там где-то будет отсутствующий закрывающий элемент).
Используя LINQ-to-XML, вы можете сделать var doc = XDocument.Load("yourfilepath")
. Оттуда просто нужно запросить нужные данные, например:
var authors = doc.Root.Elements().Select( x => x.Element("Author") );
НТН.
EDIT:
Хорошо, просто чтобы сделать этот образец лучше, попробуйте это (с улучшенным @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 файл, но все остальное должно работать. Задавайте вопросы о том, какие части вы не понимаете.
Ответ 2
в соответствии с комментарием @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);
}
Ответ 3
В качестве альтернативы вы можете использовать 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();
}
Ответ 4
Попробуйте метод GetElementsByTagName класса XMLDocument для чтения определенных данных или метода LoadXml для чтения всех данных в XML-документе.