4
\$\begingroup\$

I need a function to determine whether or not a string has HTML in it or not so that I can know whether I'm dealing with a plain-text format or HTML format.

It seems simple enough in C#, using HTMLAgilityPack. Recursively go through the tree of nodes, and if any are an element node (or comment too) then we say "Yes, it's HTML"

public static class HTMLUtility
{
    public static bool ContainsHTMLElements(string text)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(text);

        bool foundHTML =  NodeContainsHTML(doc.DocumentNode);
        return foundHTML;
    }

    private static bool NodeContainsHTML(HtmlNode node)
    {
        return node.NodeType == HtmlNodeType.Element
            || node.NodeType == HtmlNodeType.Comment
            || node.ChildNodes.Any(n => NodeContainsHTML(n));
    }
}

Am I missing anything? Thanks!

\$\endgroup\$
  • \$\begingroup\$ Can text be just any HTML element, or is it supposed to be an entire HTML document? \$\endgroup\$ – Ron Beyer Nov 17 '16 at 20:14
  • \$\begingroup\$ It could be any text that may or may not have HTML inside of it. If "text" has value "blah blah blah <div> Hello world! </div>", then then the function should return true \$\endgroup\$ – unnknown Nov 17 '16 at 20:17
  • \$\begingroup\$ If so then for any valid html it should be enough to check whether the first non-empty character is a <. \$\endgroup\$ – t3chb0t Nov 17 '16 at 20:32
5
\$\begingroup\$

I've had to do this exact thing before, your way is absolutely fine but I went for the other way round - checking if it was all text:

private static bool HtmlIsJustText(HtmlNode rootNode)
{
    return rootNode.Descendants().All(n => n.NodeType == HtmlNodeType.Text);
}

Then you have your public method as:

public static bool ContainsHTMLElements(string text)
{
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(text);
    return !HtmlIsJustText(doc.DocumentNode);
}

I think that makes the code slightly more concise.


I'd argue that your class should really be called HtmlUtility as per guidelines

The PascalCasing convention, used for all identifiers except parameter names, capitalizes the first character of each word (including acronyms over two letters in length), as shown in the following examples:

  • PropertyDescriptor
  • HtmlTag
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.