as @nwellnhof said in a separate answer, validate expects a document as a parameter, rather than a node
So I created a new document from the node and then it validates
my $xmlparser = XML::LibXML->new();
my $doc = $xmlparser->parse_string($soap);
my ($node) = $doc->findnodes('/soap:Envelope/soap:Body/*');
my $newDoc = XML::LibXML::Document->new("1.0");
$newDoc->setDocumentElement($node->cloneNode(1));
say $newDoc;
XML::LibXML::Schema->new(string => $xsd)->validate($newDoc);