Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Validate XML with schemas specified inline (xsi:schemaLocation) (with libxml or anything different from Xerces)

by jjmoka (Beadle)
on Apr 21, 2021 at 21:00 UTC ( [id://11131552]=perlquestion: print w/replies, xml ) Need Help??

jjmoka has asked for the wisdom of the Perl Monks concerning the following question:

I've been (successfully) using XML validation (against xsd/schemas specified as xsi:schemaLocation inside the XML itself)
with Xerces via this wrapping validating class:
XML::Validate
which has 3 backends for validating, one being Xerces
XML::Validate::Xerces

Just a snippet of how such XML-docs are:
 
<person xmlns="http://www.cafeconleche.org/namespaces/person"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.cafeconleche.org/namespaces/person
                      http://www.elharo.com/person.xsd">
  <name>
    <first_name>Alan</first_name>
    <last_name>Turing</last_name>
  </name>
   ...
I'm trying now to move out from Xerces (libxml or anything else)
The libxml shipped backend (of that XML::Validate):
XML::Validate::LibXML
doesn't seem anyhow able to manage the validation against xsd/schema but only against dtd.
It doesn't seem this class is going to be updated either, as it was not since 2006.

Is there any perl "standard" way nowadays to validate XML with bultin xsd/schemas in xsi:schemaLocation ?
I would have chosen XML::LibXML::Schema
which seems still the "standard" way. It also didn't receive updates since a while and it states:
Currently it supports only schema parsing and document validation.
I would then assume it doesn't support the validation from just the XML (with the inline xsi:schemaLocation)
All the examples I've found are a 2 steps process:
1. you must first know where the schema is (local or remote (if remote http only, not https)), to create an instance of XML::LibXML::Schema
2. feed this created instance with the XML-doc, to validate it.

So the only way to use that with inline xsi:schemaLocation, would seem to extract first them out from the XML-doc and get the url, create a validator instance with that location and then validate the XML-doc.
Am I missing a proper way to use this class, or am I missing any other better class ? Thank you very much to everyone.
  • Comment on Validate XML with schemas specified inline (xsi:schemaLocation) (with libxml or anything different from Xerces)
  • Select or Download Code

Replies are listed 'Best First'.
Re: Validate XML with schemas specified inline (xsi:schemaLocation) (with libxml or anything different from Xerces)
by ikegami (Patriarch) on Apr 21, 2021 at 22:04 UTC

    Generally speaking, you want to validate against a specific schema. For example, if you expect an Open Travel Alliance (OTA) request, you're going to validate against the schema for an OTA request. Or maybe you want to check that your own code generates a proper OTA request or response. Either way, you don't need xsi:schemaLocation. What this means is that ::Schema's interface is more than adequate for most people.

    To validate against the schema mentioned within the XML doc, you will to extract the schema URL yourself from the XML doc yourself. This is a rather trivial thing to do. Something like:

    my $xpc = XML::LibXML::XPathContext->new; $xpc->registerNs( xsi => 'http://www.w3.org/2001/XMLSchema-instance' ) +; my $doc = XML::LibXML->new->parse_XXX(...); my $schema_loc = $xpc->findvalue('/*/@xsi:schemaLocation', $doc) or die("...\n"); my ($schema_ns, $schema_url) = split(' ', $schema_loc); defined($schema_url) or die("...\n");

    Which you'd simply follow up with

    my $schema = XML::LibXML::Schema->new( location => $schema_url ); eval { $schema->validate($doc); 1 } or die("...\n");

    Seeking work! You can reach me at ikegami@adaelis.com

      Thank you very much. I was thinking to go for the this way, just wishing a confirmation from the experts. More than happy of your solution. Thanks again

      Fixed errors in find line.

      Seeking work! You can reach me at ikegami@adaelis.com

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11131552]
Approved by Discipulus
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-24 17:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found