SOAP::...Parser(3pm)
π SOAP::...Parser(3pm) π
okay bestie, so this is the SOAP::...Parser(3pm) page, and it's literally the lore drop on how SOAP::WSDL parses XML. no cap. let's get into it π¦
πΈ NAME πΈ
SOAP::WSDL::Manual::Parser β how SOAP::WSDL parses XML messages β¨
π¦ Which XML message does SOAP::WSDL parse ? π¦
so like, naturally there are two kinds of XML documents (or messages, same thing) that SOAP::WSDL has to parse, and there's no getting around it:
- WSDL definitions
- SOAP messages
and the thing is, there are different parser implementations available for SOAP messages vs. WSDL definitions. so don't go thinking one parser does it all π
π WSDL definitions parser π
π SOAP::WSDL::Expat::WSDLParser
this one is a parser for WSDL definitions, and it's built on top of XML::Parser::Expat. iconic.
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
my $wsdl = $parser->parse_file( $filename );
the WSDL parser creates a tree of perl objects, whose root is a SOAP::WSDL::Definitions element. like, she builds a whole lil family tree and SOAP::WSDL::Definitions is the parent π«Ά
π SOAP messages parser π
π SOAP::WSDL::Expat::MessageParser
SOAP::WSDL::Expat::MessageParser converts SOAP messages to SOAP::WSDL::XSD object trees.
it uses a class resolver to figure out which class a particular XML element should be of, plus type libs holding those classes. dynamic duo fr fr.
π Creating a class resolver
the easiest way to make a class resolver is to just run SOAP::WSDL's generator. let the machine do it.
see wsdl2perl.
the class resolver must implement a class method "get_class", which gets passed a list ref of the current element's XPath (relative to Body), split by /.
this method must return a class name appropriate for a XML element.
a class resolver package might look like this, bestie:
package ClassResolver;
my %class_list = (
'EnqueueMessage' => 'Typelib::TEnqueueMessage',
'EnqueueMessage/MMessage' => 'Typelib::TMessage',
'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI',
'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string',
);
sub new { return bless {}, 'ClassResolver' };
sub get_class {
my $name = join('/', @{ $_[1] });
return ($class_list{ $name }) ? $class_list{ $name }
: warn "no class found for $name";
};
1;
β¨ Skipping unwanted items
sometimes there's just... unnecessary information being transported in SOAP messages. we've all been there. π
to skip XML nodes (including all child nodes), just edit the type map for the message and set the type map entry to '__SKIP__'.
in the example above, EnqueueMessage/StuffIDontNeed and all child elements are skipped.
my %class_list = (
'EnqueueMessage' => 'Typelib::TEnqueueMessage',
'EnqueueMessage/MMessage' => 'Typelib::TMessage',
'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI',
'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string',
'EnqueueMessage/StuffIDontNeed' => '__SKIP__',
'EnqueueMessage/StuffIDontNeed/Foo' => 'SOAP::WSDL::XSD::Builtin::string',
'EnqueueMessage/StuffIDontNeed/Bar' => 'SOAP::WSDL::XSD::Builtin::string',
);
β οΈ note that only SOAP::WSDL::Expat::MessageParser implements skipping elements at the time of writing. so don't come for the others, they're not doing it yet π
π§ Creating type lib classes
every element must have a correspondent one in the type library. no element left behind π
builtin types should be resolved as SOAP::WSDL::XSD::Builtin::* classes
creating a type lib is easy: just run SOAP::WSDL's generator β it will create both a typemap and the type lib classes for a WSDL file. two-for-one, we love that.
sometimes it is necessary to create type lib classes by hand β because not all WSDL definitions are complete. (rude of them, honestly.)
for writing your own lib classes, see SOAP::WSDL::XSD::Typelib::Element, SOAP::WSDL::XSD::Typelib::ComplexType and SOAP::WSDL::XSD::Typelib::SimpleType.
π SOAP::WSDL::Expat::Message2Hash
transforms a SOAP message into a perl hash refs. using this parser is usually triggered by calling the "outputhash" method of SOAP::WSDL, or by using SOAP::WSDL::Deserializer::Hash.
acts somewhat like XML::Simple, but faster. β‘
the following restrictions apply, and bestie these are non-negotiable:
- Ignores all namespaces
- Ignores all attributes
- Does not handle mixed content
- The SOAP header is ignored
π OLD SAX HANDLER π
historically (iykyk), SOAP::WSDL used SAX for parsing XML. the SAX handlers were implemented as XML::LibXML handlers, which also worked with XML::SAX::ParserFactory.
support for SAX and XML::LibXML in SOAP::WSDL is discontinued, for the following reasons:
- Speed
XML::Parser::Expat is faster than XML::LibXML β at least when optimized for speed.
high parsing speed is one of the key requirements for a SOAP toolkit β if XML serializing and (more important) deserializing are not fast enough, the whole toolkit is unusable. not a vibe.
- Availability
XML::Parser is more popular than XML::LibXML. periodt.
- Stability
XML::LibXML is based on the libxml2 library. several versions of libxml2 are known to have specific bugs. as a workaround, there are often several versions of libxml2 installed on one system. this may lead to problems on operating systems which cannot load more than one version of a shared library simultaneously.
XML::LibXML is also still under development, while XML::Parser has had time to stabilize. she's grown. π±
- SOAP::Lite uses XML::Parser
SOAP::Lite uses XML::Parser if available. SOAP::WSDL should not require users to install both XML::Parser and XML::LibXML. that's just mean.
the old SAX handler historically used in SOAP::WSDL are not included in the SOAP::WSDL package any more.
however, they may be obtained from the "attic" directory in SOAP::WSDL's SVN repository at
https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/attic
SOAP::WSDL::SAX::WSDLHandler
this is a SAX handler for parsing WSDL files into object trees SOAP::WSDL works with.
it's built as a native handler for XML::LibXML, but will also work with XML::SAX::ParserFactory.
to parse a WSDL file, use one of the following variants:
my $parser = XML::LibXML->new();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new();
$parser->set_handler( $handler );
$parser->parse( $xml );
my $data = $handler->get_data();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new({
base => 'XML::SAX::Base'
});
my $parser = XML::SAX::ParserFactor->parser(
Handler => $handler
);
$parser->parse( $xml );
my $data = $handler->get_data();
SOAP::WSDL::SAX::MessageHandler
this is a SAX handler for parsing WSDL files into object trees SOAP::WSDL works with.
it's built as a native handler for XML::LibXML, but will also work with XML::SAX::ParserFactory.
can be used for parsing both streams (chunks) and documents. flexible queen π
π LICENSE AND COPYRIGHT π
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself.
π AUTHOR π
Martin Kutter <martin.kutter fen-net.de>
π¦ REPOSITORY INFORMATION π¦
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Parser.pod 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Manual/Parser.pod $
and that's the whole page bestie, we ate and left no crumbs π this was perl v5.36.0, dated 2022-10-14, stay slay, go parse something π
π¦ where this page comes from
- ubuntu noble: libsoap-wsdl-perl 3.004-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libsoap-wsdl-perl 3.004-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libsoap-wsdl-perl 3.004-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms