Html Agility Pack: DescendantsOrSelf() not returning HTML element

Posted by Program.X on Stack Overflow See other posts from Stack Overflow or by Program.X
Published on 2010-06-16T17:20:10Z Indexed on 2010/06/16 17:22 UTC
Read the original article Hit count: 383

Filed under:

I have some HTML, eg:

<%@ Page Title="About Us" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="ContentManagedTargetPage.aspx.cs" Inherits="xxx.ContentManagedTargetPage" %>
<%@ Register TagPrefix="CxCMS" Namespace="xxx.ContentManagement.ASPNET.UI" Assembly="xxx.ContentManagement.ASPNET" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Content Managed
    </h2>
    <p>
        Put content here.
        [<CxCMS:ContentManagedPlaceHolder Key="keyThingy" runat="server" />]
    </p>
</asp:Content>

And I want to find all the instances of the CxCMS:ContentManagedPlaceHolder element.

I'm using HTML Agility Pack, which seems the best fit.

However, despite looking at the [meagre] documentation, I can't get my code to work.

I would expect the following to work:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.Descendants(searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

But I get nothing back.

If I change to DescendantsOrSelf, I get the document node back, "#document" - which is incorrect:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.DescendantsOrSelf(searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

I also tried using LINQ:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.DescendantsOrSelf().Where(q=>q.Name==searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

As neither of these methods work, I moved onto using SelectNodes, instead:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
string xPath="//"+searchForElement // "//CxCMS:ContentManagedPlaceHolder"
var nodes= HtmlDocument.DocumentNode.SelectNodes(xPath);

This just throws the exception: "Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.". I can't find any way of adding namespace management to the HtmlDocument object.

What am I missing, here? The DescendantsOrSelf() method works if using a "standard" HTML tag, such as "p", but not the one I have. Surely it should work? (It needs to!)

© Stack Overflow or respective owner

Related posts about html-agility-pack