2010-02-04 4 views
1

Может ли кто-нибудь объяснить это поведение мне?XmlReader и MemoryStream, возвращаемые теги xml misses

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

вход 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), которая exaclty та же строка, но в одной строке вместо двух возвращается следующая

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> 

Единственная разница между 2 является то, что первый из них имеет разрыв строки сразу после декларации XML, но, как вы можете видеть, что второй выход попадает в родительский тег и третий тег. Любая мысль?

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

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); 
     } 
    } 

ответ

6

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

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

+0

Вы абсолютно правы; если я установил свойство 'IgnoreWhitespace' в' true' для 'XmlReaderSettings', оба примера пропускают теги. Спасибо за просвещение – Romhein