From 1e2e3a0a0eb6436d37a9bdf5058c6ac133b90001 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 8 Dec 2019 22:39:00 +0100 Subject: Validate XML with xerces. --- src/verify.cc | 299 +++-- src/verify.h | 9 +- src/wscript | 4 +- test/verify_test.cc | 65 +- tools/dcpverify.cc | 3 +- tools/wscript | 6 +- wscript | 3 +- xsd/SMPTE-429-7-2006-CPL.xsd | 208 ++++ xsd/XMLSchema.dtd | 171 +++ xsd/XMLSchema.xsd | 2534 ++++++++++++++++++++++++++++++++++++++++++ xsd/xml.xsd | 117 ++ xsd/xmldsig-core-schema.xsd | 308 +++++ 12 files changed, 3629 insertions(+), 98 deletions(-) create mode 100644 xsd/SMPTE-429-7-2006-CPL.xsd create mode 100644 xsd/XMLSchema.dtd create mode 100644 xsd/XMLSchema.xsd create mode 100644 xsd/xml.xsd create mode 100644 xsd/xmldsig-core-schema.xsd diff --git a/src/verify.cc b/src/verify.cc index bdbf4071..2815166c 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -40,9 +40,28 @@ #include "exceptions.h" #include "compose.hpp" #include "raw_convert.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include #include #include @@ -51,11 +70,13 @@ using std::list; using std::vector; using std::string; using std::cout; +using std::map; using boost::shared_ptr; using boost::optional; using boost::function; using namespace dcp; +using namespace xercesc; enum Result { RESULT_GOOD, @@ -63,6 +84,203 @@ enum Result { RESULT_BAD }; +static +string +xml_ch_to_string (XMLCh const * a) +{ + char* x = XMLString::transcode(a); + string const o(x); + XMLString::release(&x); + return o; +} + +class XMLValidationError +{ +public: + XMLValidationError (SAXParseException const & e) + : _message (xml_ch_to_string(e.getMessage())) + , _line (e.getLineNumber()) + , _column (e.getColumnNumber()) + { + + } + + string message () const { + return _message; + } + + uint64_t line () const { + return _line; + } + + uint64_t column () const { + return _column; + } + +private: + string _message; + uint64_t _line; + uint64_t _column; +}; + + +class DCPErrorHandler : public ErrorHandler +{ +public: + void warning(const SAXParseException& e) + { + maybe_add (XMLValidationError(e)); + } + + void error(const SAXParseException& e) + { + maybe_add (XMLValidationError(e)); + } + + void fatalError(const SAXParseException& e) + { + maybe_add (XMLValidationError(e)); + } + + void resetErrors() {} + + list errors () const { + return _errors; + } + +private: + void maybe_add (XMLValidationError e) + { + /* XXX: nasty hack */ + if ( + e.message() == + "schema document '/home/carl/src/libdcp/xsd/xml.xsd' has different target namespace " + "from the one specified in instance document 'http://www.w3.org/2001/03/xml.xsd'" || + e.message() == + "schema document '/home/carl/src/libdcp/xsd/xmldsig-core-schema.xsd' has different target namespace " + "from the one specified in instance document 'http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd'" + ) { + return; + } + + _errors.push_back (e); + } + + list _errors; +}; + +class StringToXMLCh : public boost::noncopyable +{ +public: + StringToXMLCh (string a) + { + _buffer = XMLString::transcode(a.c_str()); + } + + ~StringToXMLCh () + { + XMLString::release (&_buffer); + } + + XMLCh const * get () const { + return _buffer; + } + +private: + XMLCh* _buffer; +}; + +class LocalFileResolver : public EntityResolver +{ +public: + LocalFileResolver (boost::filesystem::path xsd_dtd_directory) + : _xsd_dtd_directory (xsd_dtd_directory) + { + add("http://www.w3.org/2001/XMLSchema.dtd", "XMLSchema.dtd"); + add("http://www.w3.org/2001/03/xml.xsd", "xml.xsd"); + add("http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd", "xmldsig-core-schema.xsd"); + } + + InputSource* resolveEntity(XMLCh const *, XMLCh const * system_id) + { + string system_id_str = xml_ch_to_string (system_id); + if (_files.find(system_id_str) == _files.end()) { + return 0; + } + + boost::filesystem::path p = _xsd_dtd_directory / _files[system_id_str]; + StringToXMLCh ch (p.string()); + return new LocalFileInputSource(ch.get()); + } + +private: + void add (string uri, string file) + { + _files[uri] = file; + } + + std::map _files; + boost::filesystem::path _xsd_dtd_directory; +}; + +static +list +validate_xml (boost::filesystem::path xml_file, boost::filesystem::path xsd_dtd_directory) +{ + try { + XMLPlatformUtils::Initialize (); + } catch (XMLException& e) { + throw MiscError ("Failed to initialise xerces library"); + } + + DCPErrorHandler error_handler; + + /* All the xerces objects in this scope must be destroyed before XMLPlatformUtils::Terminate() is called */ + { + XercesDOMParser parser; + parser.setValidationScheme(XercesDOMParser::Val_Always); + parser.setDoNamespaces(true); + parser.setDoSchema(true); + + map schema; + schema["http://www.w3.org/2000/09/xmldsig#"] = "xmldsig-core-schema.xsd"; + schema["http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"] = "xmldsig-core-schema.xsd"; + schema["http://www.smpte-ra.org/schemas/429-7/2006/CPL"] = "SMPTE-429-7-2006-CPL.xsd"; + schema["http://www.w3.org/2001/03/xml.xsd"] = "xml.xsd"; + + string locations; + for (map::const_iterator i = schema.begin(); i != schema.end(); ++i) { + locations += i->first; + locations += " "; + boost::filesystem::path p = xsd_dtd_directory / i->second; + locations += p.string() + " "; + } + + parser.setExternalSchemaLocation(locations.c_str()); + parser.setValidationSchemaFullChecking(true); + parser.setErrorHandler(&error_handler); + + LocalFileResolver resolver (xsd_dtd_directory); + parser.setEntityResolver(&resolver); + + try { + parser.resetDocumentPool(); + parser.parse(xml_file.string().c_str()); + } catch (XMLException& e) { + throw MiscError(xml_ch_to_string(e.getMessage())); + } catch (DOMException& e) { + throw MiscError(xml_ch_to_string(e.getMessage())); + } catch (...) { + throw MiscError("Unknown exception from xerces"); + } + + } + + XMLPlatformUtils::Terminate (); + + return error_handler.errors (); +} + static Result verify_asset (shared_ptr dcp, shared_ptr reel_mxf, function progress) { @@ -96,52 +314,17 @@ verify_asset (shared_ptr dcp, shared_ptr reel_mxf, function res; - if (!regex_match (date, res, ex, boost::match_default)) { - return false; - } - int const month = dcp::raw_convert(res[1].str()); - if (month < 1 || month > 12) { - return false; - } - int const day = dcp::raw_convert(res[2].str()); - if (day < 1 || day > 31) { - return false; - } - if (dcp::raw_convert(res[3].str()) > 23) { - return false; - } - if (dcp::raw_convert(res[4].str()) > 59) { - return false; - } - if (dcp::raw_convert(res[5].str()) > 59) { - return false; - } - if (dcp::raw_convert(res[6].str()) > 23) { - return false; - } - if (dcp::raw_convert(res[7].str()) > 59) { - return false; - } - return true; -} list -dcp::verify (vector directories, function)> stage, function progress) +dcp::verify ( + vector directories, + function)> stage, + function progress, + boost::filesystem::path xsd_dtd_directory + ) { + xsd_dtd_directory = boost::filesystem::canonical (xsd_dtd_directory); + list notes; list > dcps; @@ -162,23 +345,12 @@ dcp::verify (vector directories, function cpl, dcp->cpls()) { stage ("Checking CPL", cpl->file()); - cxml::Document cpl_doc ("CompositionPlaylist"); - cpl_doc.read_file (cpl->file().get()); - if (!good_urn_uuid(cpl_doc.string_child("Id"))) { - notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::Code::BAD_URN_UUID, string("CPL is malformed"))); - } - if (!good_date(cpl_doc.string_child("IssueDate"))) { - notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::Code::BAD_DATE, string("CPL is malformed"))); - } - /* ContentVersion/Id */ - if (cpl->standard() && cpl->standard().get() == SMPTE && !good_urn_uuid(cpl_doc.node_child("ContentVersion")->string_child("Id"))) { - notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::Code::BAD_URN_UUID, string(" is malformed."))); - } - /* Reel/Id */ - BOOST_FOREACH (cxml::ConstNodePtr i, cpl_doc.node_child("ReelList")->node_children("Reel")) { - if (!good_urn_uuid(i->string_child("Id"))) { - notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::Code::BAD_URN_UUID, string("Reel is malformed"))); - } + list errors = validate_xml (cpl->file().get(), xsd_dtd_directory); + BOOST_FOREACH (XMLValidationError i, errors) { + notes.push_back (VerificationNote( + VerificationNote::VERIFY_ERROR, VerificationNote::Code::XML_VALIDATION_ERROR, + String::compose("%1 (on line %2)", i.message(), i.line()) + )); } /* Check that the CPL's hash corresponds to the PKL */ @@ -273,12 +445,9 @@ dcp::note_to_string (dcp::VerificationNote note) return "The file for an asset in the asset map cannot be found."; case dcp::VerificationNote::MISMATCHED_STANDARD: return "The DCP contains both SMPTE and Interop parts."; - case dcp::VerificationNote::BAD_URN_UUID: - return "There is a badly-formed urn:uuid."; - case dcp::VerificationNote::BAD_DATE: - return "There is a badly-formed date."; + case dcp::VerificationNote::XML_VALIDATION_ERROR: + return "An XML file is badly formed."; } return ""; } - diff --git a/src/verify.h b/src/verify.h index 4007f8fb..9018ed46 100644 --- a/src/verify.h +++ b/src/verify.h @@ -75,10 +75,8 @@ public: MISSING_ASSET, /** The DCP contains both SMPTE and Interop-standard components */ MISMATCHED_STANDARD, - /** A urn:uuid ID is badly formed */ - BAD_URN_UUID, - /** A date is badly formed */ - BAD_DATE, + /** Some XML fails to validate against the XSD/DTD */ + XML_VALIDATION_ERROR, }; VerificationNote (Type type, Code code) @@ -124,7 +122,8 @@ private: std::list verify ( std::vector directories, boost::function)> stage, - boost::function progress + boost::function progress, + boost::filesystem::path xsd_dtd_directory ); std::string note_to_string (dcp::VerificationNote note); diff --git a/src/wscript b/src/wscript index 400d1489..85543d9d 100644 --- a/src/wscript +++ b/src/wscript @@ -197,7 +197,7 @@ def build(bld): obj.name = 'libdcp%s' % bld.env.API_VERSION obj.target = 'dcp%s' % bld.env.API_VERSION obj.export_includes = ['.'] - obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_CTH' + obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_CTH XERCES' obj.source = source # Library for gcov @@ -209,7 +209,7 @@ def build(bld): obj.name = 'libdcp%s_gcov' % bld.env.API_VERSION obj.target = 'dcp%s_gcov' % bld.env.API_VERSION obj.export_includes = ['.'] - obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_CTH' + obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_CTH XERCES' obj.use = 'libkumu-libdcp%s libasdcp-libdcp%s' % (bld.env.API_VERSION, bld.env.API_VERSION) obj.source = source obj.cppflags = ['-fprofile-arcs', '-ftest-coverage', '-fno-inline', '-fno-default-inline', '-fno-elide-constructors', '-g', '-O0'] diff --git a/test/verify_test.cc b/test/verify_test.cc index 67103ff2..737c2fb9 100644 --- a/test/verify_test.cc +++ b/test/verify_test.cc @@ -116,7 +116,7 @@ dump_notes (list const & notes) BOOST_AUTO_TEST_CASE (verify_test1) { vector directories = setup (1); - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); boost::filesystem::path const cpl_file = "build/test/verify_test1/cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"; @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE (verify_test2) BOOST_REQUIRE (fwrite (&x, sizeof(x), 1, mod) == 1); fclose (mod); - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); BOOST_REQUIRE_EQUAL (notes.size(), 2); BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_ERROR); @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE (verify_test3) e.replace ("", "x"); } - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); BOOST_REQUIRE_EQUAL (notes.size(), 3); list::const_iterator i = notes.begin(); @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE (verify_test4) e.replace ("", "x"); } - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); BOOST_REQUIRE_EQUAL (notes.size(), 1); BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::GENERAL_READ); @@ -233,7 +233,9 @@ void check_after_replace (int n, boost::function e.replace (from, to); } - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); + + dump_notes (notes); BOOST_REQUIRE_EQUAL (notes.size(), 1); BOOST_CHECK_EQUAL (notes.front().code(), code1); @@ -249,13 +251,45 @@ void check_after_replace (int n, boost::function e.replace (from, to); } - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); + + dump_notes (notes); BOOST_REQUIRE_EQUAL (notes.size(), 2); BOOST_CHECK_EQUAL (notes.front().code(), code1); BOOST_CHECK_EQUAL (notes.back().code(), code2); } +static +void check_after_replace ( + int n, boost::function file, + string from, + string to, + dcp::VerificationNote::Code code1, + dcp::VerificationNote::Code code2, + dcp::VerificationNote::Code code3 + ) +{ + vector directories = setup (n); + + { + Editor e (file(n)); + e.replace (from, to); + } + + list notes = dcp::verify (directories, &stage, &progress, "xsd"); + + dump_notes (notes); + + BOOST_REQUIRE_EQUAL (notes.size(), 3); + list::const_iterator i = notes.begin (); + BOOST_CHECK_EQUAL (i->code(), code1); + ++i; + BOOST_CHECK_EQUAL (i->code(), code2); + ++i; + BOOST_CHECK_EQUAL (i->code(), code3); +} + /* FrameRate */ BOOST_AUTO_TEST_CASE (verify_test5) { @@ -273,7 +307,7 @@ BOOST_AUTO_TEST_CASE (verify_test6) vector directories = setup (6); boost::filesystem::remove ("build/test/verify_test6/video.mxf"); - list notes = dcp::verify (directories, &stage, &progress); + list notes = dcp::verify (directories, &stage, &progress, "xsd"); BOOST_REQUIRE_EQUAL (notes.size(), 1); BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_ERROR); @@ -304,6 +338,7 @@ BOOST_AUTO_TEST_CASE (verify_test8) 8, &cpl, "http://www.smpte-ra.org/schemas/429-7/2006/CPL", "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#", dcp::VerificationNote::Code::MISMATCHED_STANDARD, + dcp::VerificationNote::Code::XML_VALIDATION_ERROR, dcp::VerificationNote::Code::CPL_HASH_INCORRECT ); } @@ -315,7 +350,7 @@ BOOST_AUTO_TEST_CASE (verify_test9) check_after_replace ( 9, &cpl, "urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b", "urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375", - dcp::VerificationNote::Code::BAD_URN_UUID + dcp::VerificationNote::Code::XML_VALIDATION_ERROR ); } @@ -325,19 +360,7 @@ BOOST_AUTO_TEST_CASE (verify_test10) check_after_replace ( 10, &cpl, "", "x", - dcp::VerificationNote::Code::BAD_DATE, + dcp::VerificationNote::Code::XML_VALIDATION_ERROR, dcp::VerificationNote::Code::CPL_HASH_INCORRECT ); } - -/* Badly formatted ContentVersion/Id */ -BOOST_AUTO_TEST_CASE (verify_test11) -{ - check_after_replace ( - 11, &cpl, - "urn:uuid:75ac29aa", "urn:uri:7fac29aa", - dcp::VerificationNote::Code::BAD_URN_UUID, - dcp::VerificationNote::Code::CPL_HASH_INCORRECT - ); -} - diff --git a/tools/dcpverify.cc b/tools/dcpverify.cc index 0c69ba78..a050d953 100644 --- a/tools/dcpverify.cc +++ b/tools/dcpverify.cc @@ -112,7 +112,8 @@ main (int argc, char* argv[]) vector directories; directories.push_back (argv[optind]); - list notes = dcp::verify (directories, bind(&stage, _1, _2), bind(&progress)); + /* XXX */ + list notes = dcp::verify (directories, bind(&stage, _1, _2), bind(&progress), "xsd"); bool failed = false; BOOST_FOREACH (dcp::VerificationNote i, notes) { diff --git a/tools/wscript b/tools/wscript index 7d0f6630..00168489 100644 --- a/tools/wscript +++ b/tools/wscript @@ -34,19 +34,19 @@ def build(bld): obj = bld(features='cxx cxxprogram') obj.use = ['libdcp%s' % bld.env.API_VERSION] - obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL' + obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL XERCES' obj.source = 'dcpdiff.cc common.cc' obj.target = 'dcpdiff' obj = bld(features='cxx cxxprogram') obj.use = ['libdcp%s' % bld.env.API_VERSION] - obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL' + obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL XERCES' obj.source = 'dcpinfo.cc common.cc' obj.target = 'dcpinfo' for f in ['dumpsub', 'decryptmxf', 'kdm', 'thumb', 'recover', 'verify']: obj = bld(features='cxx cxxprogram') obj.use = ['libdcp%s' % bld.env.API_VERSION] - obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL' + obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM BOOST_REGEX LIBXML++ XMLSEC1 OPENSSL XERCES ' obj.source = 'dcp%s.cc' % f obj.target = 'dcp%s' % f diff --git a/wscript b/wscript index 111eb5f0..1785b893 100644 --- a/wscript +++ b/wscript @@ -125,6 +125,7 @@ def configure(conf): Logs.error('Neither ImageMagick++ nor GraphicsMagick++ found: one or the other is required') conf.check_cfg(package='sndfile', args='--cflags --libs', uselib_store='SNDFILE', mandatory=False) + conf.check_cfg(package='xerces-c', args='--cflags --libs', uselib_store='XERCES', mandatory=False) if conf.options.static: if conf.options.jpeg == 'oj2': @@ -195,7 +196,7 @@ def configure(conf): libpath='/usr/local/lib', lib=['boost_date_time%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix], uselib_store='BOOST_DATETIME') - + conf.check_cxx(fragment=""" #include \n int main() { boost::regex ex("a"); }\n diff --git a/xsd/SMPTE-429-7-2006-CPL.xsd b/xsd/SMPTE-429-7-2006-CPL.xsd new file mode 100644 index 00000000..0d2c48df --- /dev/null +++ b/xsd/SMPTE-429-7-2006-CPL.xsd @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xsd/XMLSchema.dtd b/xsd/XMLSchema.dtd new file mode 100644 index 00000000..969dbb18 --- /dev/null +++ b/xsd/XMLSchema.dtd @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xsd/XMLSchema.xsd b/xsd/XMLSchema.xsd new file mode 100644 index 00000000..2e9a2729 --- /dev/null +++ b/xsd/XMLSchema.xsd @@ -0,0 +1,2534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]> + + + + Part 1 version: Id: structures.xsd,v 1.2 2004/01/15 11:34:25 ht Exp + Part 2 version: Id: datatypes.xsd,v 1.3 2004/01/23 18:11:13 ht Exp + + + + + + The schema corresponding to this document is normative, + with respect to the syntactic constraints it expresses in the + XML Schema language. The documentation (within <documentation> elements) + below, is not normative, but rather highlights important aspects of + the W3C Recommendation of which this is a part + + + + + The simpleType element and all of its members are defined + towards the end of this schema document + + + + + + Get access to the xml: attribute groups for xml:lang + as declared on 'schema' and 'documentation' below + + + + + + + + This type is extended by almost all schema types + to allow attributes from other namespaces to be + added to user schemas. + + + + + + + + + + + + + This type is extended by all types which allow annotation + other than <schema> itself + + + + + + + + + + + + + + + + This group is for the + elements which occur freely at the top level of schemas. + All of their types are based on the "annotated" type by extension. + + + + + + + + + + + + + This group is for the + elements which can self-redefine (see <redefine> below). + + + + + + + + + + + + + A utility type, not for public use + + + + + + + + + + + A utility type, not for public use + + + + + + + + + + + A utility type, not for public use + + #all or (possibly empty) subset of {extension, restriction} + + + + + + + + + + + + + + + + + A utility type, not for public use + + + + + + + + + + + + + A utility type, not for public use + + #all or (possibly empty) subset of {extension, restriction, list, union} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + for maxOccurs + + + + + + + + + + + + for all particles + + + + + + + for element, group and attributeGroup, + which both define and reference + + + + + + + + 'complexType' uses this + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This branch is short for + <complexContent> + <restriction base="xs:anyType"> + ... + </restriction> + </complexContent> + + + + + + + + + + + + + + + Will be restricted to required or forbidden + + + + + + Not allowed if simpleContent child is chosen. + May be overriden by setting on complexContent child. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This choice is added simply to + make this a valid restriction per the REC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overrides any setting on complexType parent. + + + + + + + + + + + + + + + This choice is added simply to + make this a valid restriction per the REC + + + + + + + + + + + + + + + + + No typeDefParticle group reference + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A utility type, not for public use + + #all or (possibly empty) subset of {substitution, extension, + restriction} + + + + + + + + + + + + + + + + + + + + + + + + + The element element can be used either + at the top level to define an element-type binding globally, + or within a content model to either reference a globally-defined + element or type or declare an element-type binding locally. + The ref form is not allowed at the top level. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group type for explicit groups, named top-level groups and + group references + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group type for the three kinds of group + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This choice with min/max is here to + avoid a pblm with the Elt:All/Choice/Seq + Particle derivation constraint + + + + + + + + + + restricted max/min + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Only elements allowed inside + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + simple type for the value of the 'namespace' attr of + 'any' and 'anyAttribute' + + + + Value is + ##any - - any non-conflicting WFXML/attribute at all + + ##other - - any non-conflicting WFXML/attribute from + namespace other than targetNS + + ##local - - any unqualified non-conflicting WFXML/attribute + + one or - - any non-conflicting WFXML/attribute from + more URI the listed namespaces + references + (space separated) + + ##targetNamespace or ##local may appear in the above list, to + refer to the targetNamespace of the enclosing + schema or an absent targetNamespace respectively + + + + + + A utility type, not for public use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A subset of XPath expressions for use +in selectors + A utility type, not for public +use + + + + The following pattern is intended to allow XPath + expressions per the following EBNF: + Selector ::= Path ( '|' Path )* + Path ::= ('.//')? Step ( '/' Step )* + Step ::= '.' | NameTest + NameTest ::= QName | '*' | NCName ':' '*' + child:: is also allowed + + + + + + + + + + + + + + + + + + + + + + + A subset of XPath expressions for use +in fields + A utility type, not for public +use + + + + The following pattern is intended to allow XPath + expressions per the same EBNF as for selector, + with the following change: + Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) + + + + + + + + + + + + + + + + + + + + + + + + + + + The three kinds of identity constraints, all with + type of or derived from 'keybase'. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A utility type, not for public use + + A public identifier, per ISO 8879 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + notations for use within XML Schema schemas + + + + + + + + + Not the real urType, but as close an approximation as we can + get in the XML representation + + + + + + + + + + First the built-in primitive datatypes. These definitions are for + information only, the real built-in definitions are magic. + + + + For each built-in datatype in this schema (both primitive and + derived) can be uniquely addressed via a URI constructed + as follows: + 1) the base URI is the URI of the XML Schema namespace + 2) the fragment identifier is the name of the datatype + + For example, to address the int datatype, the URI is: + + http://www.w3.org/2001/XMLSchema#int + + Additionally, each facet definition element can be uniquely + addressed via a URI constructed as follows: + 1) the base URI is the URI of the XML Schema namespace + 2) the fragment identifier is the name of the facet + + For example, to address the maxInclusive facet, the URI is: + + http://www.w3.org/2001/XMLSchema#maxInclusive + + Additionally, each facet usage in a built-in datatype definition + can be uniquely addressed via a URI constructed as follows: + 1) the base URI is the URI of the XML Schema namespace + 2) the fragment identifier is the name of the datatype, followed + by a period (".") followed by the name of the facet + + For example, to address the usage of the maxInclusive facet in + the definition of int, the URI is: + + http://www.w3.org/2001/XMLSchema#int.maxInclusive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NOTATION cannot be used directly in a schema; rather a type + must be derived from it by specifying at least one enumeration + facet whose value is the name of a NOTATION declared in the + schema. + + + + + + + + + + Now the derived primitive types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pattern specifies the content of section 2.12 of XML 1.0e2 + and RFC 3066 (Revised version of RFC 1766). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pattern matches production 7 from the XML spec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pattern matches production 5 from the XML spec + + + + + + + + + + + + + + + pattern matches production 4 from the Namespaces in XML spec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A utility type, not for public use + + + + + + + + + + + + + + + + + + + + + + #all or (possibly empty) subset of {restriction, union, list} + + + A utility type, not for public use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Can be restricted to required or forbidden + + + + + + + + + + + + + + + + + + Required at the top level + + + + + + + + + + + + + + + + + + + Forbidden when nested + + + + + + + + + + + + + + + + + + + We should use a substitution group for facets, but + that's ruled out because it would allow users to + add their own, which we're not ready for yet. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + base attribute and simpleType child are mutually + exclusive, but one or other is required + + + + + + + + + + + + + + + + itemType attribute and simpleType child are mutually + exclusive, but one or other is required + + + + + + + + + + + + + + + + + + memberTypes attribute must be non-empty or there must be + at least one simpleType child + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xsd/xml.xsd b/xsd/xml.xsd new file mode 100644 index 00000000..d662b423 --- /dev/null +++ b/xsd/xml.xsd @@ -0,0 +1,117 @@ + + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang or xml:space attributes + on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2001/03/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself. In other words, if the XML Schema namespace changes, the version + of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2001/03/xml.xsd will not change. + + + + + + In due course, we should install the relevant ISO 2- and 3-letter + codes as the enumerated possible values . . . + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + + + + + diff --git a/xsd/xmldsig-core-schema.xsd b/xsd/xmldsig-core-schema.xsd new file mode 100644 index 00000000..f30e1b24 --- /dev/null +++ b/xsd/xmldsig-core-schema.xsd @@ -0,0 +1,308 @@ + + + + + + ]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3