Прочитать следующее значение в файле XML
У меня есть такой XML-файл:
<key>businessAddress</key>
<string>Moka</string>
<key>businessName</key>
<string>Moka address</string>
<key>Id</key>
<string>39</string>
<key>Cat</key>
<string>216</string>
<key>deals</key>
Я хочу прочитать следующее <string>
значение, если ключ является идентификатором
Итак, что я сделал, это:
XmlTextReader reader = new XmlTextReader(file);
while (reader.Read())
{
if (reader.Value.Equals("Id"))
{
reader.MoveToNextAttribute
}
}
но мне не удалось.
Спасибо за помощь
3 ответа
Вы можете использовать логический флаг, чтобы указать, следует ли читать значение следующего элемента:
bool shouldReadId = false;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text && shouldReadId)
{
Console.WriteLine(reader.Value); // will print 39
shouldReadId = false;
}
if (reader.Value.Equals("Id"))
{
// indicate that we should read the value of the next element
// in the next iteration
shouldReadId = true;
}
}
Я хотел бы отметить, что XmlTextReader в основном заменен XmlReader:
Начиная с.NET Framework 2.0, мы рекомендуем вместо этого использовать класс System.Xml.XmlReader.
Хотя их объектная модель ничем не отличается.
Итак, если вы хотите использовать XmlTextReader, вы можете сделать что-то вроде:
public static class XmlReaderExtensions
{
public static void EnsureRead(this XmlTextReader reader)
{
var isRead = reader.Read();
if (!isRead)
throw new InvalidOperationException("Failed to read");
}
public static void SkipUntil(this XmlTextReader reader, Func<XmlTextReader, Boolean> isStop)
{
while (!isStop(reader))
{
reader.EnsureRead();
}
}
}
...
var xml = @"<root> <key>businessAddress</key>
<string>Moka</string>
<key>businessName</key>
<string>Moka address</string>
<key>Id</key>
<string>39</string>
<key>Cat</key>
<string>216</string>
<key>deals</key> </root>";
using (var stream = new MemoryStream(Encoding.Default.GetBytes(xml)))
using (var reader = new XmlTextReader(stream))
{
reader.SkipUntil(cur => cur.Value == "Id");
reader.EnsureRead(); // Skip current node
reader.SkipUntil(cur => cur.NodeType == XmlNodeType.Text);
Console.WriteLine("The id from XmlTextReader is {0}", reader.Value);
}
Хотя, чтобы быть уверенным, что это будет работать правильно быстро потерпеть неудачу с некоторым XML, который не соответствует данной схеме, вам придется добавить немного больше проверок работоспособности, так что...
Вы также можете попробовать LINQ-TO-XML, если вы не заинтересованы в том, чтобы все дерево XML помещалось в память:
using (var stream = new MemoryStream(Encoding.Default.GetBytes(xml)))
{
var xdoc = XDocument.Load(stream);
var id = xdoc
.Root
.Elements("key")
.First(element =>
element.Value == "Id")
.ElementsAfterSelf("string")
.First()
.Value;
Console.WriteLine("The id from XDocument is {0}", id);
}
Ваш XML выглядит подозрительно похожим на Plist. Похоже, вам нужна библиотека Plist. Вместо того, чтобы изобретать велосипед, просто используйте любую из библиотек, доступных в NuGet. Они решат ваши проблемы с анализом XML-файла.
Если вы настаиваете на синтаксическом анализе XML вручную, забудьте о низкоуровневом классе SAX и просто используйте DOM. Работать с XDocument
намного проще Смотрите решение @EugenePodskal.