XmlReader и MemoryStream, возвращаемый xml пропускает теги - PullRequest
1 голос
/ 04 февраля 2010

Может ли кто-нибудь объяснить мне это поведение?

Если вы выполняете фрагмент в нижней части поста с первой строкой, он возвращает точно такую ​​же строку, которая использовалась для ввода; это то, что я ожидал.

вход 1:

<?xml version='1.0' encoding='UTF-8'?>
<Company>
  <Creator>Me</Creator>
  <CreationDateTime>2010-01-25T21:58:32.493</CreationDateTime>
  <Contacts>
    <Contact>
      <ContactID>365</ContactID>
    </Contact>
  </Contacts>
</Company>

вывод 1:

<?xml version='1.0' encoding='UTF-8'?>
<Company>
  <Creator>Me</Creator>
  <CreationDateTime>2010-01-25T21:58:32.493</CreationDateTime>
  <Contacts>
    <Contact>
      <ContactID>365</ContactID>
    </Contact>
  </Contacts>
</Company>

Теперь, если вы используете вторую строку (const string xml), которая является точно такой же строкой, но в одной строке вместо двух, она возвращает следующее

intput 2

<?xml version='1.0' encoding='UTF-8'?>
<Company>
  <Creator>Me</Creator>
  <CreationDateTime>2010-01-25T21:58:32.493</CreationDateTime>
  <Contacts>
    <Contact>
      <ContactID>365</ContactID>
    </Contact>
  </Contacts>
</Company>

вывод 2

<?xml version='1.0' encoding='UTF-8'?>
<Creator>Me</Creator>2010-01-25T21:58:32.493 
<Contacts>
  <Contact>
    <ContactID>365</ContactID>
  </Contact>
</Contacts>

Единственное различие между двумя состоит в том, что у первого есть разрыв строки сразу после объявления xml, но, как вы можете видеть, во втором выводе пропущен тег Parent и третий тег. Есть мысли?

Вот код, который я использовал:

public void XmlReader_Eats_Tags_IsTrue()
    {
        //this first xml declaration is on two lines - line break is right after the xml declaration (I am not sure how to add the line break using the markdown, so if you execute the code on your machine, please add it)
        const string xml = @"<?xml version='1.0' encoding='UTF-8'?><Company><Creator>Me</Creator><CreationDateTime>2010-01-25T21:58:32.493</CreationDateTime><Contacts><Contact><ContactID>365</ContactID></Contact></Contacts></Company>";

        //The seconde xml declaration is on one line
        //const string xml = @"<?xml version='1.0' encoding='UTF-8'?><Company><Creator>Me</Creator><CreationDateTime>2010-01-25T21:58:32.493</CreationDateTime><Contacts><Contact><ContactID>365</ContactID></Contact></Contacts></Company>";

        BufferedStream stream = new BufferedStream(new MemoryStream());
        stream.Write(Encoding.ASCII.GetBytes(xml), 0, xml.Length);
        stream.Seek(0, SeekOrigin.Begin);
        StreamReader streamReaderXml = new StreamReader(stream);

        XmlReader xmlR = XmlReader.Create(streamReaderXml);

        XmlReaderSettings xmlReaderset = 
                         new XmlReaderSettings{ValidationType = ValidationType.Schema};
        xmlReaderset.Schemas.ValidationEventHandler += ValidationCallBack;

        MemoryStream ms = new MemoryStream();
        XmlWriterSettings xmlWriterSettings = 
                          new XmlWriterSettings{
                                  Encoding = new UTF8Encoding(false),
                                  ConformanceLevel = ConformanceLevel.Fragment
                          };

        using (XmlWriter xmlTw = XmlWriter.Create(ms, xmlWriterSettings))
        {
            using (XmlReader xmlRead = XmlReader.Create(xmlR, xmlReaderset))
            {
                int i = 0;
                while (xmlRead.Read())
                {
                    Console.WriteLine("{0}:{1}; node type: {2}", i, xmlRead.Name, xmlRead.NodeType);
                    // Reads the whole file and will call the validation handler subroutine if an error is detected.
                    xmlTw.WriteNode(xmlRead, true);
                    i++;
                }

                xmlTw.Flush();
                xmlRead.Close();
            }
            string xmlString = Encoding.UTF8.GetString(ms.ToArray());
            Console.WriteLine(xmlString);
        }
    }

1 Ответ

6 голосов
/ 04 февраля 2010

Проблема в том, что вы используете XmlWriter.WriteNode(reader, true) и для вызова XmlReader.Read().WriteNode уже перемещает считыватель на элемент брата, поэтому вы фактически пропускаете данные при повторном вызове Read.

Я подозреваю, что случается, работает впервая версия, потому что вы пропускаете пробелы во втором вызове Read, а затем читаете остальную часть документа во втором вызове WriteNode.

...