2010-02-04 39 views
1

有人可以向我解釋這種行爲嗎?XmlReader和MemoryStream,返回的XML錯過標籤

如果您使用第一個字符串在帖子底部執行片段,它將返回與用於輸入的字符串完全相同的字符串;這就是我的預期。

輸入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

你是絕對正確的;如果我爲'XmlReaderSettings'設置'IgnoreWhitespace'屬性爲'true',那麼這兩個示例都會跳過這些標籤。感謝您的啓發 – Romhein 2010-02-04 13:59:37