Не видя ваш код, трудно действительно дать прямой ответ на этот вопрос. Однако я могу предложить использовать Linq-to-XML вместо XMLReader / XMLWriter - с ним намного проще работать, когда вам не нужно читать каждый узел по одному и определять, с каким узлом вы работаете, какой звучит как проблема, с которой вы столкнулись.
Например, код типа:
using (var reader = new XmlReader(...))
{
while reader.Read()
{
if (reader.Name = "book" && reader.IsStartElement)
{
// endless, confusing nesting!!!
}
}
}
становится:
var elem = doc.Descendants("book").Descendants("title")
.Where(c => c.Attribute("name").Value == "C# Basics")
.FirstOrDefault();
Для ознакомления с LINQ-to-XML, посмотрите http://www.c -sharpcorner.com / UploadFile / shakthee / 2868 / или просто найдите «Linq-to-XML». Существует множество примеров.
Редактировать: Я попробовал ваш код и смог воспроизвести вашу проблему. Кажется, что без новой строки перед тегом special
первый элемент special
читается как IsStartElement() == false
. Я не был уверен, почему это так; даже пролистал XML Specification и не видел никаких требований к переводу строки перед элементами.
Я переписал ваш код в Linq-to-XML, и он работал без каких-либо переносов:
var xdoc = XDocument.Load(filename);
var barElement = xdoc.Element("AggievilleBar");
var specialElements = barElement.Descendants("special").ToList();
var specials = new List<Special>();
specialElements.ForEach(s =>
{
var dayOfWeek = Convert.ToInt32(s.Attribute("dayofweek").Value);
var price = Convert.ToInt32(s.Attribute("price").Value);
var date = s.Attribute("date");
specials.Add(new Special
{
Name = s.Value,
DayOfWeek = dayOfWeek,
Price = price,
Date = date != null ? DateTime.Parse(date.Value) : DateTime.MinValue
});
});
var bar = new Bar() {
Name = barElement.Element("name").Value,
PictureVersion = Convert.ToInt32(barElement.Elements("picture").Single()
.Attribute("version").Value),
Location = barElement.Element("location").Value,
Description = barElement.Element("description").Value,
News = barElement.Element("news").Value,
Specials = specials
};
return bar;
Рассматриваете ли вы использование Linq-to-XML вместо XMLReader? В прошлом у меня были проблемы с XMLReader, и как только я перешел на Linq-to-XML, я больше не оглядывался назад!
РЕДАКТИРОВАТЬ: Я знаю, что этот вопрос довольно старый сейчас, но я только что наткнулся на статью, которая напомнила мне об этом вопросе и может объяснить, почему это происходит: -> http://www.codeproject.com/KB/dotnet/pitfalls_xml_4_0.aspx
Автор утверждает:
В этом свете неприятное различие между XmlReaders / Writers и XDocument заключается в способе обработки пробелов. (См. http://msdn.microsoft.com/en-us/library/bb387014.aspx.)
Из MSDN:
В большинстве случаев, если метод принимает LoadOptions в качестве аргумента, вы можете дополнительно сохранить незначительный пробел в качестве текстовых узлов в дереве XML. Однако, если метод загружает XML из XmlReader, XmlReader определяет, будет ли сохранено пустое пространство. Установка PreserveWhitespace не будет иметь никакого эффекта.
Так что, возможно, поскольку вы загружаете с помощью XmlReader, XmlReader решает, должен ли он сохранять пробел. Скорее всего, он сохраняет пробел, поэтому новая строка (или ее отсутствие) имеет значение. И кажется, что вы ничего не можете изменить, если вы используете XmlReader! Очень своеобразно.