/// <summary> /// Returns the pos'th child with the given tagName. /// </summary> public static IHtmlElement GetChildAt(this IHtmlElement parent, string tagName, int pos) { parent.Require(x => parent != null); tagName.Require(x => !string.IsNullOrEmpty(tagName)); int childPos = 0; foreach (var child in parent.Children) { if (child.TagName.Equals(tagName, StringComparison.OrdinalIgnoreCase)) { if (childPos == pos) { return(child); } childPos++; } } return(null); // TODO: this could happen if the site has been changed and the // path is no longer valid //throw new ArgumentException( "Could not find child for path: " + tagName + "[" + pos + "]" ); }
/// <summary> /// Returns the position of the HtmlElement in its parents children. /// </summary> public static int GetChildPos(this IHtmlElement element) { element.Require(x => element != null); if (element.Parent == null) { // assume its valid HTML with <html/> as root element return(0); } int childPos = 0; foreach (var child in element.Parent.Children) { if (child.TagName.Equals(element.TagName, StringComparison.OrdinalIgnoreCase)) { if (child == element) { return(childPos); } childPos++; } } //throw new ArgumentException( "Could not find child pos for child: " + e.TagName ); return(-1); }
/// <summary> /// Searches for the parent of the given elment for which <c>cond</c> /// gets <c>true</c>. /// Stops the search and returns null if <c>abortIf</c> gets true before /// <c>cond</c> gets true. /// The given element must not fullfil the abort condition. /// </summary> /// <returns>the parent found if any, null otherwise</returns> public static IHtmlElement FindParent(this IHtmlElement start, Predicate <IHtmlElement> cond, Predicate <IHtmlElement> abortIf) { start.Require(x => start != null); start.Require(x => !abortIf(start)); var parent = start.Parent; while (parent != null && !abortIf(parent)) { if (cond(parent)) { return(parent); } parent = parent.Parent; } return(null); }
/// <summary> /// Gets the complete row of the given cell. /// </summary> public static IEnumerable <IHtmlElement> GetRow(IHtmlElement cell) { cell.Require(x => cell != null); var row = GetEmbeddingTR(cell); if (row == null) { throw new ArgumentException("Element does not point to cell inside table row"); } return(row.Children); }
/// <summary> /// Searches for the table which embedds the given element. /// If the start element is a TABLE element, this one is returned. /// </summary> public static HtmlTable FindEmbeddingTable(this IHtmlElement start) { start.Require(x => start != null); if (start.TagName == "TABLE") { return(new HtmlTable(start)); } var table = start.FindParent(p => p.TagName == "TABLE"); return(table == null ? null : new HtmlTable(table)); }
/// <summary> /// Returns the TR element embedding the given element. /// If the given element itself is a TR, this one is returned. /// </summary> public static IHtmlElement GetEmbeddingTR(IHtmlElement e) { e.Require(x => e != null); if (e.TagName == "TR") { return(e); } else { var parent = e.FindParent(p => p.TagName == "TR", p => e.IsTableOrTBody()); return(parent == null ? null : parent); } }
/// <summary> /// Returns the <see cref="HtmlPath"/> of the HtmlElement up to root. /// </summary> public static HtmlPath GetPath(this IHtmlElement element) { element.Require(x => element != null); HtmlPath path = new HtmlPath(); var cur = element; while (cur.Parent != null) { path.Elements.Insert(0, new HtmlPathElement(cur.TagName, cur.GetChildPos())); cur = cur.Parent; } return(path); }
/// <summary> /// Gets the complete column of the given cell. /// <remarks>Attention: Handling "colspan" is not implemented. /// A TR without any TD is skipped.</remarks> /// </summary> public static IEnumerable <IHtmlElement> GetColumn(IHtmlElement cell) { cell.Require(x => cell != null); HtmlTable table = cell.FindEmbeddingTable(); if (table == null) { throw new ArgumentException("Element does not point to into table"); } int colIdx = cell.GetChildPos(); foreach (object row in table.TableBody.Children) { IHtmlElement e = ((IHtmlElement)row).GetChildAt("TD", colIdx); if (e == null) { continue; } yield return(e); } }
/// <summary> /// Gets the complete row of the given cell. /// </summary> public static IEnumerable<IHtmlElement> GetRow( IHtmlElement cell ) { cell.Require( x => cell != null ); var row = GetEmbeddingTR( cell ); if ( row == null ) { throw new ArgumentException( "Element does not point to cell inside table row" ); } return row.Children; }
/// <summary> /// Returns the TR element embedding the given element. /// If the given element itself is a TR, this one is returned. /// </summary> public static IHtmlElement GetEmbeddingTR( IHtmlElement e ) { e.Require( x => e != null ); if ( e.TagName == "TR" ) { return e; } else { var parent = e.FindParent( p => p.TagName == "TR", p => e.IsTableOrTBody() ); return (parent == null ? null : parent); } }
/// <summary> /// Gets the complete column of the given cell. /// <remarks>Attention: Handling "colspan" is not implemented. /// A TR without any TD is skipped.</remarks> /// </summary> public static IEnumerable<IHtmlElement> GetColumn( IHtmlElement cell ) { cell.Require( x => cell != null ); HtmlTable table = cell.FindEmbeddingTable(); if ( table == null ) { throw new ArgumentException( "Element does not point to into table" ); } int colIdx = cell.GetChildPos(); foreach ( object row in table.TableBody.Children ) { IHtmlElement e = ((IHtmlElement)row).GetChildAt( "TD", colIdx ); if ( e == null ) { continue; } yield return e; } }