2015-05-20 93 views
1

我正在爲我的需要編寫自定義XML解析。該程序的目的是解析任何類型的與主節點相匹配的XML文件。 我已經複製了下面的問題。 ReadXml(),ParseData()方法讀取XML元素的數據的主要目的是否匹配,否則它應該前進到下一個節點。 但是輸入的XML有一個額外的Node'title1',因爲這個節點解析程序在沒有閱讀'author'節點的情況下破壞了。XmlReader無法讀取所有節點

class Program 
{ 
    static void Main() 
    { 
     StringBuilder output = new StringBuilder(); 

     String xmlString = 
      @"<bookstore> 
        <book genre='autobiography' publicationdate='1981-03-22' ISBN='1-861003-11-0'> 
         <title>The Autobiography of Benjamin Franklin</title> 
         <title1>The Autobiography of Benjamin Franklin</title1>       
         <author>       
          <first-name>Benjamin</first-name> 
          <last-name>Franklin</last-name>       
         </author> 
         <author2> 
          <first-name>Benjamin</first-name> 
          <last-name>Franklin</last-name> 
         </author2> 
         <price>8.99</price> 
        </book> 
       </bookstore>"; 

     // Create an XmlReader 
     using (XmlReader reader = XmlReader.Create(new StringReader(xmlString))) 
     { 
      ReadXml(reader); 
     } 
    } 



    public static void ReadXml(System.Xml.XmlReader reader) 
    { 
     if (reader.MoveToContent() == XmlNodeType.Element && 
      reader.LocalName == "bookstore") 
     { 
      reader.Read(); 
      // Parse the file and display each of the nodes. 
      do 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         ParseData(reader); 
         break; 
        case XmlNodeType.Text: 
        case XmlNodeType.CDATA: 
        case XmlNodeType.ProcessingInstruction: 
        case XmlNodeType.Comment: 
        case XmlNodeType.XmlDeclaration: 
        case XmlNodeType.Document: 
        case XmlNodeType.EntityReference: 
        case XmlNodeType.EndElement: 
         break; 
       } 

       if (reader.ReadState == ReadState.Interactive) 
        reader.Read(); 

      } while (!reader.EOF && reader.NodeType != XmlNodeType.EndElement); 

     } 
    } 


    protected static bool ParseData(System.Xml.XmlReader reader) 
    { 
     string output = string.Empty; 
     bool parsed = true; 
     switch (reader.LocalName) 
     { 
      case "title": 
       output = reader.ReadString(); 
       break;    
      case "author": 
       XmlReader reagentListReader = reader.ReadSubtree();  // This case never reached    
       break;    
      default: 
       // output = reader.ReadString(); //uncomment will work,But        //not sure to read subtree or string. 
       parsed = false; 
       break; 
     } 
     return parsed; 
    } 
} 

通過添加'output = reader.ReadString();'在默認情況下:switch case解決了我的問題,但我永遠不知道它是讀取Subtree或String。

+0

有你解析這樣的理由? 「真正的」文件是否非常大? –

+0

是的,真正的文件較大,可以增長到任意大小。真實文件可以由不同的用戶更新併發送給客戶。該軟件應該在任何特定場景下處理新的XML。 – Srikanth

+0

當你想忽略某些標籤時,你應該讀取整個子樹。 –

回答

2

問題是你的循環條件 - 你退出,因爲當它達到EndElement。你可以通過它來驗證這一點 - 當你調用reader.Read時,你會忽略那些元素。

只要改變條件:

while (!reader.EOF); 
+0

這是行得通的,但文件的大小和程序的性能是一個問題。 – Srikanth

+0

你能解釋爲什麼reader.Read()沒有移動到下一個節點,而是迭代文本,命令.. – Srikanth

+0

這就是它的工作原理,它按順序讀取所有部分,例如元素,屬性,內容(可能包含更多元素),然後是結束元素。 –