2010-04-29 89 views
1

我試圖構建一個簡單的XML來控制我的CF應用程序中的解析器。 在字符串IM下面的代碼試圖解析如下所示:使用XMLReader解析問題(使用ReadSubTree)

"<Panel><Label>Text1</Label><Label>Text2</Label></Panel>" 

我想這段代碼的結果將是有兩個標籤的面板。 但問題是當解析第一個標籤時,subreader.Read()在ParsePanelElementh方法中返回false,因此它脫離了while語句。 由於即時通訊新的XMLReader我一定會錯過一些非常簡單的東西。 任何幫助將被認爲是!

平安。

static class XMLParser 
{ 
    public static Control Parse(string aXmlString) 
    { 
     XmlReader reader = XmlReader.Create(new StringReader(aXmlString)); 
     return ParseXML(reader); 
    } 

    public static Control ParseXML(XmlReader reader) 
    { 
     using (reader) 
     { 
      while (reader.Read()) 
      { 
       if (reader.NodeType == XmlNodeType.Element) 
       { 
        if (reader.LocalName == "Panel") 
        { 
         return ParsePanelElement(reader); 
        } 

        if (reader.LocalName == "Label") 
        { 
         return ParseLabelElement(reader); 
        } 
       } 
      } 
     } 
     return null; 
    } 

    private static Control ParsePanelElement(XmlReader reader) 
    { 
     var myPanel = new Panel(); 
     XmlReader subReader = reader.ReadSubtree(); 
     while (subReader.Read()) 
     { 
      Control subControl = ParseXML(subReader); 
      if (subControl != null) 
      { 
       myPanel.Controls.Add(subControl); 
      }; 
     } 
     return myPanel; 
    } 

    private static Control ParseLabelElement(XmlReader reader) 
    { 
     reader.Read(); 
     var myString = reader.Value as string; 
     var myLabel = new Label(); 
     myLabel.Text = myString; 
     return myLabel; 
    } 
} 

回答

3

的問題是,讀者ParseXML讀取兩次,一次在ParsePanelElement一次。這樣你解析面板,跳過第一個標籤,並最終添加第二個標籤。

[EDIT 2010年5月3日]

的Visual Studio 9.根據此代碼的工作(I移到了使用條款)

static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
     Control Test = XMLParser.Parse("<Panel><Label>Text1</Label><Label>Text2</Label></Panel>"); 
     for (Int32 i = 0; i < Test.Controls.Count; i++) 
     { 
      System.Diagnostics.Debug.WriteLine("Control " + i + ": " + Test.Controls[i].GetType().FullName + " [TEXT = " + Test.Controls[i].Text + "]"); 
     } 
     } 

     static class XMLParser 
     { 
     public static Control Parse(string aXmlString) 
     { 
      Control result = null; 
      using (StringReader strReader = new StringReader(aXmlString)) 
      { 
       using (XmlReader reader = XmlReader.Create(strReader)) 
       { 
        result = ParseXML(reader); 
       } 
      } 
      return result; 
     } 

     public static Control ParseXML(XmlReader reader) 
     { 
      while (reader.Read()) 
      { 
       if (reader.NodeType == XmlNodeType.Element) 
       { 
        if (reader.LocalName == "Panel") 
        { 
        return ParsePanelElement(reader); 
        } 

        if (reader.LocalName == "Label") 
        { 
        return ParseLabelElement(reader); 
        } 
       } 
      } 
      return null; 
     } 

     private static Control ParsePanelElement(XmlReader reader) 
     { 
      var myPanel = new Panel(); 
      using (XmlReader subReader = reader.ReadSubtree()) 
      { 
       while (subReader.Read()) 
       { 
        Control subControl = ParseXML(subReader); 
        if (subControl != null) 
        { 
        myPanel.Controls.Add(subControl); 
        }; 
       } 
      } 
      return myPanel; 
     } 

     private static Control ParseLabelElement(XmlReader reader) 
     { 
      reader.Read(); 
      var myString = reader.Value as string; 
      var myLabel = new Label(); 
      myLabel.Text = myString; 
      return myLabel; 
     } 
     } 
    } 
+0

結果IM剛開僅與第一標籤面板。在ParsePanelElement我讀subReader而不是原來的讀者。既然它是一個簡單的例子,你能修復我的代碼嗎,所以我明白我做錯了什麼? – no9 2010-04-29 10:55:22

+0

我以爲我在ParseLabelElement中發現了這個問題。 我替換爲:「reader.Read(); var myString = reader.Value as string;」到「var myString = reader.ReadElementContentAsString();」。 但問題仍然存在,因爲當這被稱爲讀者位置改變到下一個節點(在我的情況下第二個標籤)。有沒有辦法讀取節點值並保持相同的位置? – no9 2010-04-29 12:34:22

+0

是reader.Read()在那一點上必需的嗎?我現在無法檢查,因爲我沒有Visual Studio在這裏。看起來在'ParsePanelElement'中你讀了第一個節點,當'ParsePanelElement'調用'ParseXml'時你讀了另一個節點,並且當'parseXml'調用'ParseLabelElement'你讀了另一個節點。 另外,這是否使用聲明工作?我認爲只有在聲明一個新的分配對象時才使用語句?如果確實有效,這也可能是你的問題的原因。 using語句關閉子閱讀器,while循環退出。 – Roy 2010-04-29 21:27:50