From d6a854cadd70c4df5fa83df58f5126a81aca43b9 Mon Sep 17 00:00:00 2001 From: David Nichols Date: Mon, 28 Dec 2015 14:35:32 +0100 Subject: [PATCH] refs qorelanguage/qore#318 implemented support for default namespace handling for XSD types, updated tests + relnotes --- RELEASE-NOTES | 1 + docs/mainpage.doxygen.tmpl | 1 + qlib/WSDL.qm | 72 ++++++++++++++++++++++++++++++-------- test/test.wsdl | 4 +-- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 1bb3354..2181104 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -20,6 +20,7 @@ version 1.3 + allow for XSD imports without a URI scheme to be imported with custom logic + allow for schema definitions to temporarily override namespace prefixes within that schema + + implemented support for default namespace handling for base types * SoapClient fixes: + fixed URI request path + fixed agent string diff --git a/docs/mainpage.doxygen.tmpl b/docs/mainpage.doxygen.tmpl index 15184a1..884dcd6 100644 --- a/docs/mainpage.doxygen.tmpl +++ b/docs/mainpage.doxygen.tmpl @@ -273,6 +273,7 @@ printf("%s\n", make_xml($h, XGF_ADD_FORMATTING));@endcode - perform environment-variable substitution on the file path in WSDLLib::getWSDL() - better support for empty elements; correct de/serialization depending on element and type properties - allow for schema definitions to temporarily override namespace prefixes within that schema + - implemented support for default namespace handling for base types - SoapClient fixes: - fixed URI request path - fixed agent string diff --git a/qlib/WSDL.qm b/qlib/WSDL.qm index 07ecd41..299dfa9 100644 --- a/qlib/WSDL.qm +++ b/qlib/WSDL.qm @@ -2390,13 +2390,35 @@ class WSDL::NamespacePrefixHelper { # overriden prefixes hash h; + + # overridden target namespace + bool targ_ns; + + # overridden default namespace + bool def_ns; } - constructor(Namespaces n_nsc) { + constructor(Namespaces n_nsc, *hash nsattr) { nsc = n_nsc; + + if (nsattr) { + nsc.addNamespaces(nsattr, self); + if (nsattr.targetNamespace) { + nsc.pushTargetNamespace(nsattr.targetNamespace); + targ_ns = True; + } + if (nsattr.xmlns) { + nsc.pushDefaultNamespace(nsattr.xmlns); + def_ns = True; + } + } } destructor() { + if (def_ns) + nsc.popDefaultNamespace(); + if (targ_ns) + nsc.popTargetNamespace(); if (h) nsc.restorePrefixes(h); } @@ -2449,6 +2471,12 @@ public class WSDL::Namespaces { #! target namespace stack; list nss = (); + + #! default namespace for unprefixed definitions + *string default_ns; + + #! default namespace stack; + list dss = (); } #! creates the object with the WSDL definitions attribute hash @@ -2458,16 +2486,20 @@ public class WSDL::Namespaces { if (nsh.targetNamespace) target_ns = nsh.targetNamespace; + # set default namespace for unprefixed definitions + if (nsh.xmlns) + default_ns = nsh.xmlns; + #printf("*** DEBUG: Namespaces::constructor() %y\n", nsh); addNamespaces(nsh); - # "default" has to be quoted because it's a reserved word - if (nsh.xmlns) - ns."default" = nsh.xmlns; - #ns.target = nsh.targetNamespace; #printf("*** DEBUG: Namespaces::constructor() imap: %y\n", imap); } + *string getDefaultNs() { + return default_ns; + } + addNamespaces(hash nsh, *NamespacePrefixHelper nph) { foreach string k in (nsh.keyIterator()) { *string ns = (k =~ x/xmlns:(\w+)/)[0]; @@ -2581,7 +2613,7 @@ public class WSDL::Namespaces { return getTargetNamespaceUri(); } - #! pushes the previous target namespace URI on the stack when parsing schemas and sets the current target namespace URI to the current value + #! pushes the current target namespace URI on the stack when parsing schemas and sets the current target namespace URI to the current value pushTargetNamespace(string ns) { nss += target_ns; target_ns = ns; @@ -2592,6 +2624,17 @@ public class WSDL::Namespaces { target_ns = pop nss; } + #! pushes the current default namespace URI on the stack when parsing schemas and sets the current default namespace URI to the current value + pushDefaultNamespace(string ns) { + dss += default_ns; + default_ns = ns; + } + + #! restores any previous default namespace URI from the stack to the current default namespace URI + popDefaultNamespace() { + default_ns = pop dss; + } + #! looks up and registers a namespace if necessary, returns the namespace's prefix string getOutputNamespacePrefix(string ns) { *string nsa = nsr{ns}; @@ -2649,8 +2692,13 @@ public class WSDL::Namespaces { any doType(string t) { #printf("DEBUG: XsdBase::doType(%y)\n", t); (*string ns, *string type) = t =~ x/(\w+):(\w+)/; - if (!type) + if (!type) { + #printf("DEBUG: XsdBase::doType(%y) xsd: %y\n", t, default_ns); + if (default_ns == XSD_NS) + return new XsdBaseType(t, self, getTargetNamespaceInputPrefix()); + return ("val": t); + } # if this is in the XML Schema namespace, then it's a base type if (xml_schema{ns}) @@ -2862,7 +2910,7 @@ public class WSDL::WebService inherits WSDL::XsdBase { } private XsdAbstractType resolveType(hash v) { - if (v.ns && nsc.isSchema(v.ns)) + if (exists v.ns && nsc.isSchema(v.ns)) return getBaseType(v.val); # find type @@ -2879,16 +2927,10 @@ public class WSDL::WebService inherits WSDL::XsdBase { *hash sa = schema."^attributes^"; #if (!sa) # throw "OOPS"; - NamespacePrefixHelper nph(nsc); - if (sa) - nsc.addNamespaces(sa, nph); + NamespacePrefixHelper nph(nsc, sa); if (sa.elementFormDefault == "qualified") usedocns = True; - if (sa.targetNamespace) - nsc.pushTargetNamespace(sa.targetNamespace); - on_exit if (sa.targetNamespace) - nsc.popTargetNamespace(); #printf("DEBUG: schema tn: %y\n", schema."^attributes^"."targetNamespace"); WSDL::XsdBase::removeNS(\schema); diff --git a/test/test.wsdl b/test/test.wsdl index d067c7e..586c81c 100644 --- a/test/test.wsdl +++ b/test/test.wsdl @@ -1,12 +1,12 @@ - + - +