XmlReader получить значение без перемещения курсора вперед - PullRequest
0 голосов
/ 28 апреля 2018

Это пропуск строк, когда reader.ReadString() перемещает курсор вперед. reader.Value пусто.

Как я могу прочитать этот XML в List<LogData> logDatas = new List<LogData>();?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Xml;
using System.IO;

namespace ReadXML
{
    class Program
    {
        private static string XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine +
                                    "<log>" + Environment.NewLine +
                                    "    <logData id=\"Alpha\">"              + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>100</index>"          + Environment.NewLine +
                                    "            <value>150</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>110</index>"          + Environment.NewLine +
                                    "            <value>750</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>115</index>"          + Environment.NewLine +
                                    "            <value>150</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>110</index>"          + Environment.NewLine +
                                    "            <value>750</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>120</index>"          + Environment.NewLine +
                                    "            <value>750</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>130</index>"          + Environment.NewLine +
                                    "            <value>150</value>"          + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "    </logData>"                          + Environment.NewLine +
                                    "    <logData id=\"Bravo\">"              + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>100</index>"          + Environment.NewLine +
                                    "            <value>25</value></data>"    + Environment.NewLine +
                                    "        <data>"                          + Environment.NewLine +
                                    "            <index>110</index>"          + Environment.NewLine +
                                    "            <value>11</value>"           + Environment.NewLine +
                                    "        </data>"                         + Environment.NewLine +
                                    "    </logData>"                          + Environment.NewLine +
                                    "</log>";
        }
        public static List<LogData> GetLogDatas(string xml)
        {
            List<LogData> logDatas = new List<LogData>();
            string wasteFile = "wasteFile.xml";
            File.WriteAllText(wasteFile, xml);
            using (XmlReader reader = XmlReader.Create(wasteFile))
            {
                while (reader.Read())
                {
                    if (reader.IsStartElement())
                    {
                        Debug.WriteLine($"LocalName            {reader.LocalName}");
                        if (reader.HasAttributes)
                            Debug.WriteLine($"Attribute:           {reader.GetAttribute("id")}");
                        //Debug.WriteLine($"Value1               {reader.Value}");  //this is empty
                        Debug.WriteLine($"Value2               {reader.ReadString()}");
                    }
                    else
                    {
                        //Debug.WriteLine("not IsStartElement");
                    }
                }
            }
            return logDatas;
        }
    }
    public class LogData
    {
        public string ID { get; }
        public List<LogPoint> LogPoints { get; } = new List<LogPoint>();
        public LogData (string id)
        {
            ID = id;
        }
    }
    public class LogPoint
    {
        public int Index { get; }
        public double Value { get; }
        public LogPoint ( int index, double value)
        {
            Index = index;
            Value = value;
        }
    }
}

1 Ответ

0 голосов
/ 28 апреля 2018

Не уверен, что вы ожидаете от текущего кода, но для синтаксического анализа данного xml с заданной структурой данных разумным подходом является следующее:

public static List<LogData> GetLogDatas(string xml) {
    List<LogData> logDatas = new List<LogData>();
    // no need for waste file, use StringReader
    using (var sreader = new StringReader(xml))
    using (XmlReader reader = XmlReader.Create(sreader)) {
        LogData currentData = null;
        while (reader.Read()) {
            if (reader.IsStartElement("logData")) {
                // we are positioned on start of logData
                if (currentData != null)
                    logDatas.Add(currentData);
                currentData = new LogData(reader.GetAttribute("id"));
            }
            else if (reader.IsStartElement("data")) {
                // we are on start of "data"
                // we always have "currentData" at this point                        
                Debug.Assert(currentData != null);
                reader.ReadToFollowing("index");
                var index = int.Parse(reader.ReadElementContentAsString());
                // check if we are not already on "value"
                if (!reader.IsStartElement("value"))
                    reader.ReadToFollowing("value");
                var value = double.Parse(reader.ReadElementContentAsString(), CultureInfo.InvariantCulture);
                currentData.LogPoints.Add(new LogPoint(index, value));
            }
        }

        if (currentData != null)
            logDatas.Add(currentData);
    }

    return logDatas;
}
...