public static function sortNodes($nodes)
    {
        // saves node paths
        foreach ($nodes as $node) {
            if (!isset($node->__path__)) {
                $node->__path__ = Dom::_getNodePath($node);
            }
        }

        // sorts elements in the same order they appear in the document
        usort(
            $nodes,
            function ($node0, $node1) {
                $path0 = $node0->__path__;
                $path1 = $node1->__path__;
                $count0 = count($path0);
                $count1 = count($path1);
                $len = min($count0, $count1);

                for ($i = 0; $i < $len; $i++) {
                    if ($path0[$i] != $path1[$i]) {
                        return $path0[$i] > $path1[$i];
                    }
                }

                return $count0 > $count1;
            }
        );
        
        // unsets __path__
        foreach ($nodes as $node) {
            unset($node->__path__);
        }
        
        return $nodes;
    }