# /=====================================================================\ #
# | LaTeXML::Common::XML::RelaxNG | #
# | wrapper for XML::LibXML | #
# |=====================================================================| #
# | Part of LaTeXML: | #
# | Public domain software, produced as part of work done by the | #
# | United States Government & not subject to copyright in the US. | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package
LaTeXML::Common::XML::RelaxNG;
use
strict;
use
warnings;
use
XML::LibXML;
# Note: XML::LibXML::RelaxNG->new(...) takes
# location=>$filename_or_url;
# string=>$schemastring
# DOM=>$doc
# options: nocatalogs, searchpaths
# Create a Wrapper for a RelaxNG,
# containing the XML document representing the schema
# defering converting it to an actual RelaxNG object.
sub
new {
my
(
$class
,
$name
,
%options
) =
@_
;
LaTeXML::Common::XML::initialize_catalogs();
my
$xmlparser
= LaTeXML::Common::XML::Parser->new();
my
$schemadoc
;
$name
.=
".rng"
unless
$name
=~ /\.rng$/;
# First, try to load directly, in case it's found via libxml's catalogs...
# But be careful calling C library; its failures are harder to trap w/eval
if
(!
$options
{nocatalogs}) {
$schemadoc
=
eval
{
local
$LaTeXML::IGNORE_ERRORS
= 1;
no
warnings
'all'
;
$xmlparser
->parseFile(
$name
); }; }
if
(!
$schemadoc
) {
if
(
my
$path
= pathname_find(
$name
,
paths
=>
$options
{searchpaths} || [
'.'
],
types
=> [
'rng'
],
# Eventually, rnc?
installation_subdir
=>
'resources/RelaxNG'
)) {
# Hopefully, just a file, not a URL?
$schemadoc
=
$xmlparser
->parseFile(
$path
); }
else
{
return
;
# ???
} }
return
bless
{
schemadoc
=>
$schemadoc
},
$class
; }
sub
validate {
my
(
$self
,
$document
) =
@_
;
# Lazy conversion of the Schema's XML doc into an actual RelaxNG object.
if
(!
$$self
{schema} &&
$$self
{schemadoc}) {
$$self
{schema} = XML::LibXML::RelaxNG->new(
DOM
=>
$$self
{schemadoc}); }
return
$$self
{schema}->validate(
$document
); }
# This returns the root element of the XML document representing the schema!
sub
documentElement {
my
(
$self
) =
@_
;
return
$$self
{schemadoc}->documentElement; }
sub
URI {
my
(
$self
) =
@_
;
return
$$self
{schemadoc}->URI; }
#======================================================================
1;