XMLReader пропускает элементы - PullRequest
0 голосов
/ 17 июня 2020

У меня есть следующий файл XML (с фиктивными данными)

<Query>
    <QuerySQL Source="Dbname" Sql="SQL statement" />
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="SQL statement" />
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="SQL statement" />
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="SQL statement" />
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="SQL statement" />
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="Sql statement">
      <Parameters>
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
      </Parameters>
    </QuerySQL>
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="Sql statement">
      <Parameters>
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
      </Parameters>
    </QuerySQL>
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="Sql statement">
      <Parameters>
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
      </Parameters>
    </QuerySQL>
  </Query>
  <Query>
    <QuerySQL Source="Dbname" Sql="Sql statement">
      <Parameters>
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
        <Parameter Type="Type" />
      </Parameters>
    </QuerySQL>
  </Query>

Проблема в том, что первые элементы запроса отлично читаются в моем XMLReader.

Затем, когда он попадает те, у которых есть параметры, пропускает все остальные запросы.

Я не могу понять почему. Это просто вообще не отображается в ридере.

Вот мой метод чтения:

StringReader stringReader = new StringReader(xmlString.ToString());
      using (XmlReader reader = XmlReader.Create(stringReader, GetXmlReaderSettings())) {
        while (reader.Read() && !reader.EOF) {
          if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "Query")) {
            if (reader.ReadToDescendant("QuerySQL")) {
              m_sqlQuery = reader.GetAttribute("Sql");
              m_doublePointCounter = m_sqlQuery.Split(':').Length - 1;
              m_source = reader.GetAttribute("Source");
              if (reader.ReadToDescendant("Parameters")) {
                while (reader.ReadToFollowing("Parameter") && m_parameterCount < m_doublePointCounter) {
                  m_parameterCount++;
                  var types = reader.GetAttribute("Type");
                  m_paramList.Add(types);
                }
              }
            }
          }
}

Надеюсь, кто-нибудь может помочь мне разобраться в этом.

Что мне нужно, так это способ прочитать каждый элемент запроса и прочитать его.

Ответы [ 3 ]

1 голос
/ 18 июня 2020

Метод ReadToFollowing проходит через все элементы Parameter.
Чтобы избежать этого, вам нужно прочитать поддерево.

if (reader.ReadToDescendant("Parameters"))
{
    using (var innerReader = reader.ReadSubtree())
    {
        while (innerReader.ReadToFollowing("Parameter") && m_parameterCount < m_doublePointCounter)
        {
            m_parameterCount++;
            var types = innerReader.GetAttribute("Type");
            m_paramList.Add(types);
        }
    }
}
0 голосов
/ 17 июня 2020

Ваш XML неправильно сформирован - у вас несколько тегов <Query> root. Чтобы сделать XML действительным, вам необходимо вложить этот повторяющийся тег <Query> в тег root.

Пока вы не исправите эту проблему, вы ничего не сможете сделать - XML процессоры требуются , чтобы отклонить ваш входной файл. Я не удивлен, что LINQ не смог его обработать. Я очень удивлен, что вы не получили ошибку синтаксического анализа в опубликованном вами коде.

0 голосов
/ 17 июня 2020

Попробуйте xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;



namespace ConsoleApplication4
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            XDocument doc = XDocument.Parse(xml);

            var results = doc.Descendants("Query").Select(x => new
            {
                source = (string)x.Element("QuerySQL").Attribute("Source"),
                sql = (string)x.Element("QuerySQL").Attribute("Sql"),
                parameters = x.Descendants("Parameter").Select(y => new { type = (string)y.Attribute("Type") }).ToList()
            }).ToList();


        }
    }


}
...