code: private static void recursiveFindBadNodesInTable(Node n, Node cellroot, Vector<Node> nodes)
      {
          Node cell = cellroot;
          
          if (n.getNodeType() == Node.ELEMENT_NODE)
          {
              String tag = n.getNodeName();
              if (tag.equalsIgnoreCase("table"))
              {
                  if (cell != null) //do not enter nested tables
                      return;
              }
              else if (tag.equalsIgnoreCase("tbody") || 
                       tag.equalsIgnoreCase("thead") || 
                       tag.equalsIgnoreCase("tfoot") ||
                       tag.equalsIgnoreCase("tr") ||
                       tag.equalsIgnoreCase("col") ||
                       tag.equalsIgnoreCase("colgroup"))
              {
              }
              else if (tag.equalsIgnoreCase("td") || tag.equalsIgnoreCase("th") || tag.equalsIgnoreCase("caption"))
              {
                  cell = n;
              }
              else //other elements
              {
                  if (cell == null)
                  {
                      nodes.add(n);
                      return;
                  }
              }
          } //other nodes
          else if (n.getNodeType() == Node.TEXT_NODE)
          {
              if (cell == null && n.getNodeValue().trim().length() > 0)
              {
                  nodes.add(n);
                  return;
              }
          }
          
          NodeList child = n.getChildNodes();
          for (int i = 0; i < child.getLength(); i++)
              recursiveFindBadNodesInTable(child.item(i), cell, nodes);
      }
docs: Finds all the nodes in a table that cannot be contained in the table according to the HTML syntax.
  @param n table root
  @param cellroot last cell root
  @param nodes resulting list of nodes