使用XMLReader解析问题(使用ReadSubTree)

时间:2010-04-29 10:40:59

标签: c# compact-framework xmlreader

我试图在我的CF应用程序中构建一个简单的XML to Controls解析器。 在下面的代码中,我试图解析的字符串如下所示:

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

我希望这个代码的结果是一个带有两个标签的Panel。 但问题是当第一个Label被解析时,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;
    }
}

1 个答案:

答案 0 :(得分:3)

问题是读者读取两次,一次在ParsePanelElement,一次在ParseXML。这样您就可以解析面板,跳过第一个标签并最终添加第二个标签。

[编辑2010年5月3日]

此代码适用于Visual Studio 9.(我已移动using子句)

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