2010-02-04 2 views
1

Quelqu'un pourrait-il m'expliquer ce comportement?XmlReader et MemoryStream, le xml renvoyé manque des balises

Si vous exécutez l'extrait au bas du message avec la première chaîne, il renvoie exactement la même chaîne que celle utilisée pour l'entrée; c'est ce à quoi je m'attendais.

entrée 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> 

sortie 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> 

Maintenant, si vous utilisez la deuxième ligne (const string xml), qui est exaclty la même chaîne, mais sur une seule ligne au lieu de deux, il retourne le

suivant

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> 

sortie 2

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

La seule différence entre les deux est que le premier a un saut de ligne droite après la déclaration xml mais comme vous pouvez voir la deuxième sortie passe à côté de la balise Parent et la troisième balise. Toute pensée?

Voici le code je:

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

Répondre

6

Le problème est que vous utilisez XmlWriter.WriteNode(reader, true)et appelant XmlReader.Read(). WriteNode déplace déjà le lecteur sur l'élément frère, de sorte que vous ignorez les données lorsque vous appelez de nouveau Read.

Je soupçonne que ce arrive à travailler dans la première version, car vous sauter sur les espaces blancs du deuxième appel à Read, puis lire le reste du document dans le deuxième appel à WriteNode.

+0

Vous avez absolument raison; si je définis la propriété 'IgnoreWhitespace' sur' true' pour 'XmlReaderSettings', les deux exemples ignorent les balises. Merci pour l'illumination – Romhein