[Soap-Python] Customizing rpclib with types that modify the schema

Burak Arslan burak.arslan at arskom.com.tr
Fri Mar 30 00:57:53 CEST 2012


Hi,

I thought if I'd just start implementing this, it'd help you more than a 
300-word reply.

I skimmed the spec very quick and from what I gather, you want an <any> 
tag instead of an <element> tag inside the <complexType><sequence> (...) 
</complexType></sequence> hierarchy, right? (correct me if i'm wrong here.)

if so, here's the patch that is a nice starting point:

diff --git a/src/rpclib/interface/xml_schema/model/complex.py 
b/src/rpclib/interface/xml_schema/model/complex.py
index f99f587..ae0d65c 100644
--- a/src/rpclib/interface/xml_schema/model/complex.py
+++ b/src/rpclib/interface/xml_schema/model/complex.py
@@ -22,6 +22,7 @@ from lxml import etree
  from rpclib.const import xml_ns as namespace
  from rpclib.model import ModelBase
  from rpclib.model.complex import XmlAttribute
+from rpclib.model.primitive import AnyXml
  from rpclib.util.etreeconv import dict_to_etree

  def complex_add(interface, cls):
@@ -82,9 +83,21 @@ def complex_add(interface, cls):
              if v != cls:
                  interface.add(v)

-            member = etree.SubElement(sequence, '{%s}element' % 
namespace.xsd)
-            member.set('name', k)
-            member.set('type', v.get_type_name_ns(interface))
+            member = etree.SubElement(sequence, v.Attributes.schema_tag)
+            if v.Attributes.schema_tag == '{%s}element' % namespace.xsd:
+                member.set('name', k)
+                member.set('type', v.get_type_name_ns(interface))
+
+            elif v.Attributes.schema_tag == '{%s}any' % namespace.xsd and \
+                    (v is AnyXml or
+                        (hasattr(v, '_is_clone_of') and v._is_clone_of 
is AnyXml)):
+                if v.Attributes.namespace is not None:
+                    member.set('namespace', v.Attributes.namespace)
+                if v.Attributes.process_contents is not None:
+                    member.set('processContents', 
v.Attributes.process_contents)
+
+            else:
+                raise ValueError("Unhandled schema_tag / type 
combination.")

              if v.Attributes.min_occurs != 1: # 1 is the xml schema default
                  member.set('minOccurs', str(v.Attributes.min_occurs))
diff --git a/src/rpclib/model/_base.py b/src/rpclib/model/_base.py
index 32d5fe7..abf80b1 100644
--- a/src/rpclib/model/_base.py
+++ b/src/rpclib/model/_base.py
@@ -89,6 +89,10 @@ class ModelBase(object):
          will imply an iterable of objects as native python type. Can 
be set to
          ``float("inf")`` for arbitrary number of arguments."""

+        schema_tag = '{%s}element' % rpclib.const.xml_ns.xsd
+        """The tag used to add a primitives as child to a complex type 
in the
+        xml schema."""
+
      class Annotations(object):
          """The class that holds the annotations for the given type."""

diff --git a/src/rpclib/model/primitive.py b/src/rpclib/model/primitive.py
index 9fc2b6a..9ee2a94 100644
--- a/src/rpclib/model/primitive.py
+++ b/src/rpclib/model/primitive.py
@@ -74,6 +74,13 @@ class AnyXml(SimpleModel):

      __type_name__ = 'anyType'

+    class Attributes(SimpleModel.Attributes):
+        namespace = None
+        """Xml-Schema specific namespace attribute"""
+
+        process_contents = None
+        """Xml-Schema specific processContents attribute"""
+
      @classmethod
      @nillable_string
      def to_string(cls, value):


The first hunk makes the element tag name parametric.

The second hunk adds the parameter to the ModelBase class.

So if you want an <any> tag instead of an <element> tag inside a 
complexType definition, you need to do this:

class SomeType(ComplexModel):
     child = AnyXml(schema_tag='{%s}any' % rpclib.const.xml_ns.xsd, 
namespace='##other')

This is totally off the top of my head, but I guess you get the idea.

Does this help? Let me know how it goes.

best,
burak

On 03/29/12 19:32, Alex Railean wrote:
> 3. change the code that generates a Python object from XML

there's no such thing in rpclib. we don't parse xml schema, only 
generate it.


>     - I think it can rely on validate_native, but my understanding is
>       that I must also define the behaviour of validate_native for this
>       type - I don't know where to do that
>

You need to re-implement any additional validation that the the schema 
validation does in the soft validator as well. In this case, I agree 
that validate_native in AnyXml is the right place to do it.




More information about the Soap mailing list