Heyho,
Ich hatte gerade ein wenig Zeit übrig und dachte ich setze mich an die Realisierung von einer sehr sehr einfachen HTML Engine. Habe nach Ideen zum Vorgehen im Internet gesucht und bin auf eine Seite gestoßen, die den Lexer Zeichen für Zeichen realisiert. Das ist doch ein wenig zu aufwändig und da HTML (zumindest XHMTL, dass Tags wie <br> dann unter den Tisch fallen ist mir bewusst) schön gleichmäßig geformt ist, dachte ich das schreit nach RegEx und Rekursion. Soweit so gut:
Zur Erklärung: Die Methode matcht einen umschließenden Tag und ruft sich selbst mit dem Inhalt des Tags wieder auf. Anschließend wird der gefundene Tag aus dem Suchstring gelöscht, sodass als nächstes die Geschwister gefunden werden:
Das funltioniert auch soweit richtig gut . Nur leider ignoriert das Ding Mischungen aus Text und ElementNodes was den Parser recht unbrauchbar macht.
Beispiel:
Hat jemand ne Idee wie man das intelligent beheben kann?
Ich hatte gerade ein wenig Zeit übrig und dachte ich setze mich an die Realisierung von einer sehr sehr einfachen HTML Engine. Habe nach Ideen zum Vorgehen im Internet gesucht und bin auf eine Seite gestoßen, die den Lexer Zeichen für Zeichen realisiert. Das ist doch ein wenig zu aufwändig und da HTML (zumindest XHMTL, dass Tags wie <br> dann unter den Tisch fallen ist mir bewusst) schön gleichmäßig geformt ist, dachte ich das schreit nach RegEx und Rekursion. Soweit so gut:
C#-Quellcode
- class Node
- {
- public string Tag { get; set; }
- public List<Node> SubNodes { get; set; }
- public List<string> Class { get; set; }
- public string ID { get; set; }
- public Dictionary<String, String> Properties = new Dictionary<string, string>();
- public string Text { get; set; }
- public Node(string _Tag, string _Text ) {
- SubNodes = new List<Node>();
- this.Tag = _Tag;
- this.Text = _Text;
- }
- public void addProperty(string property, string propertyvalue) {
- if (property.ToLower().Equals("class"))
- {
- this.Class.Add(propertyvalue);
- }
- else if (property.ToLower().Equals("id"))
- {
- this.ID = propertyvalue;
- }
- else
- {
- Properties.Add(property, propertyvalue);
- }
- }
- public void addChildren(List<Node> nd) {
- if(nd!=null)
- SubNodes.AddRange(nd);
- }
- public void addChild(Node nd)
- {
- if (nd != null)
- SubNodes.Add(nd);
- }
- }
C#-Quellcode
- public List<Node> parseHTML(string html) {
- Regex rgx = new Regex("<(.*?)(\\s(.*?)=\"(.*?)\")*>(.*?)</\\1>");
- html = html.Trim();
- List<Node> nodes = new List<Node>();
- Match mt = rgx.Match(html);
- while (mt.Success) {
- Node parent = new Node(mt.Groups[1].Value, "");
- //add the attribute values
- var props = mt.Groups[3];
- for(int i = 0; i< props.Captures.Count; i++)
- {
- parent.addProperty(props.Captures[i].Value, mt.Groups[4].Captures[i].Value);
- }
- string subnodecontent = mt.Groups[5].Value;
- if (rgx.IsMatch(subnodecontent))
- {
- //add all childrens
- parent.addChildren(parseHTML(subnodecontent));
- }
- else
- {
- Node textnode = new Node("", subnodecontent);
- parent.addChild(textnode);
- }
- //add the node
- nodes.Add(parent);
- //remove current match and move on
- html = html.Remove(mt.Index, mt.Length).Trim();
- mt = rgx.Match(html);
- }
- return nodes;
- }
Zur Erklärung: Die Methode matcht einen umschließenden Tag und ruft sich selbst mit dem Inhalt des Tags wieder auf. Anschließend wird der gefundene Tag aus dem Suchstring gelöscht, sodass als nächstes die Geschwister gefunden werden:
Das funltioniert auch soweit richtig gut . Nur leider ignoriert das Ding Mischungen aus Text und ElementNodes was den Parser recht unbrauchbar macht.
Beispiel:
Hat jemand ne Idee wie man das intelligent beheben kann?
faxe1008