两次使用linq

时间:2018-10-01 08:29:58

标签: c# xml linq

我正在尝试读取xml文件。然后提取一些有用的数据以绘制图形。.我已经实现了所需的输出。.但问题是我的程序两次读取xml文件以提取有用的数据。.这需要一些额外的时间。是否有其他方法只能一次读取文件。 ?谢谢

<?xml version="1.0" encoding="UTF-8"?>
<CanConformanceTesterLog Version="4.1">
  <TestProperties>
    <Item name="IUT Name" value="Reference"/>
    <Item name="PG Clock Period" value="1000 ns"/>
</TestProperties>
  <SignalData SamplingPeriod="1000.000 ns" DataWidth="16 bit">
    <Signal>
      <Id>IUT_RX</Id>
      <InitState>1</InitState>
      <![CDATA[HQFPAVkBiwGVAZ8BqQHHAdEBAwINAjUCPwJxAnsCrQK3AsEC1QLzAv0CEQMbAzkDTQNrA3UDfwOJA7sDxQPtA/cDKQQzBEcEUQSDBI0EtQTJBN0E5wTxBAUFDwUZBS0FNwVBBUsFVQWHFZEVmxWlFa8VuRXDFc0V1xXhFesV9RX/FTEWOxZFFk8WgRaLFpUWnxapFscW0RbbFuUW7xYDFyEXPxdJF1MXGhgkGC4YTBhWGHQYfhiwGLoY2BjiGBQZHhkoGTIZUBlaGXgZghmgGaoZvhnbGeUZ9RwTHR0dTx1ZHYsdlR29Hccd+R0DHg0eFx5JHlMeZx6ZHsEe6R4lH5Qfsh+8H+4f+B8qIDQgXCBmIJggoiCsILYg6CDyIAYhOCFgIYghxCEzIlEiWyKNIpciySLTIvsiBSM3I0EjSyNVI4cjmyOlI9cj/yMTJB0kpyaxJrsmxSbPJgEnCyc9J0cnZSdvJ6EnqyfdJ+cnGSgjKC0oQShLKF8ocyiHKJsopSivKLkowyjWKOAo8jQkNS41YDVqNZw1pjXENc41ADYKNhQ2HjZGNlA2WjZkNm42eDaWNqo2tDbHNtE2uDd=]]>
    </Signal>
    <Signal>
      <Id>IUT_TX</Id>
      <InitState>1</InitState>
      <![CDATA[SwVVBYcVkRWbFaUVrxW5FcMVzRXXFeEV6xX1Ff8VMRY7FkUWTxaBFosWlRafFqkWxxbRFtsW5RbvFgMXIRc/FxoYJBguGEwYVhh0GH4YsBi6GNgY4hgUGR4ZKBkyGVAZWhl4GYIZoBmqGb4Z6B4kH4ghxCETJB0kpyaxJrsmxSbPJgEnCyc9J0cnZSdvJ6EnqyfdJ+cnGSgjKC0oQShLKF8ocyiHKJsopSivKLkowyjyNCQ1LjVgNWo1nDWmNcQ1zjUANgo2FDYeNkY2UDZaNmQ2bjZ4NpY2qja0Nrg3]]>
    </Signal>
</SignalData>
</CanConformanceTesterLog>

我具有读取标记“ SignalData”的数据的函数。然后在读取此数据后,它将调用另一个函数并传递xml文件的名称,dataWidth,samplingPeriod。 然后,第二个功能读取“ Signal”标签。然后从每个“ Signal”中提取数据。最后,当一切完成后,就会调用一个函数来绘制图形...

private bool SignalDataInfo(string fileName)
        {
            var xdoc = XDocument.Load(fileName);
            if (xdoc != null)
            {
                var signalData = xdoc.Descendants("SignalData");
                foreach (var signal in signalData)
                {
                    var width = signal.Attribute("DataWidth").Value;
                    string dataWidth = width.Substring(0, width.IndexOf(" "));
                    var period = signal.Attribute("SamplingPeriod").Value;
                    string samplingPeriod = period.Substring(0, period.IndexOf(" "));
                    SignalData(fileName,dataWidth, samplingPeriod);
                }
                return true;
            }
            else
                return false;
        }

public bool SignalData(string fileName,string width, string period)
        {var xdoc = XDocument.Load(fileName);
            if (xdoc != null)
            {
                var signalData = xdoc.Descendants("Signal");

                foreach (var signal in signalData)
                { // extract data from every signal }
return true;
else false;
}

2 个答案:

答案 0 :(得分:0)

您只需保存一个类变量(例如private XDocument xDoc;)中已加载的XDocument即可加载XML文件,而不必在每个方法上创建一个实例。同样,如果仅分别检索XML数据(在这种情况下,可以使用loadData()方法来初始化数据)将有帮助。这也将使您的代码以某种方式分离关注点。参见下面的代码:

private XDocument xDoc;

private void loadData(string fileName)
{
   xDoc = XDocument.Load(fileName);
}

private bool SignalDataInfo()
        {
            if (xDoc != null)
            {
                var signalData = xDoc.Descendants("SignalData");
                foreach (var signal in signalData)
                {
                    var width = signal.Attribute("DataWidth").Value;
                    string dataWidth = width.Substring(0, width.IndexOf(" "));
                    var period = signal.Attribute("SamplingPeriod").Value;
                    string samplingPeriod = period.Substring(0, period.IndexOf(" "));
                    SignalData(fileName,dataWidth, samplingPeriod);
                }
                return true;
            }
            else
                return false;
        }

public bool SignalData(string width, string period)
        {
            if (xDoc != null)
            {
                var signalData = xDoc.Descendants("Signal");

                foreach (var signal in signalData)
                { // extract data from every signal }
return true;
else false;
}

希望这会有所帮助!

答案 1 :(得分:0)

在这里,我创建了一个示例控制台应用程序供您从SignalDataSignal两者中提取数据。

我想您会在搜索下面的代码。

在下面的代码片段中,您将在程序中使用result来读取xml中的数据。

因此,通过这种方式,您不必每次调用方法时都编写两种不同的方法并加载xml。

class Program
{
    static void Main(string[] args)
    {
        XDocument doc = XDocument.Load(@"Your xml document path");

        var result = (from o in doc.Descendants("SignalData")
                      from i in o.Descendants("Signal")
                      select new
                      {
                          dataWidth = o.Attribute("DataWidth").Value.Substring(0, o.Attribute("DataWidth").Value.IndexOf(" ")),
                          period = o.Attribute("SamplingPeriod").Value.Substring(0, o.Attribute("SamplingPeriod").Value.IndexOf(" ")),
                          Id = i.Elements("Id").Select(item => (string)item).FirstOrDefault(),
                          InitState = i.Elements("InitState").Select(item => (string)item).FirstOrDefault(),
                          cdata = i.Value
                      }).ToList();

        foreach (var item in result)
        {
            Console.WriteLine($"dataWidth: { item.dataWidth}, \t period: {item.period}, \t Id: {item.Id}, \t InitState: {item.InitState}");
        }

        Console.ReadLine();
    }
}

输出cdata已从输出中排除。

enter image description here