1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Provides sx typing classes.
19 """
20
21 from logging import getLogger
22 from suds import *
23 from suds.mx import *
24 from suds.sax import Namespace as NS
25 from suds.sax.text import Text
26
27 log = getLogger(__name__)
31 """
32 Provides XML node typing as either automatic or manual.
33 @cvar types: A dict of class to xs type mapping.
34 @type types: dict
35 """
36
37 types = {
38 int : ('int', NS.xsdns),
39 long : ('long', NS.xsdns),
40 float : ('float', NS.xsdns),
41 str : ('string', NS.xsdns),
42 unicode : ('string', NS.xsdns),
43 Text : ('string', NS.xsdns),
44 bool : ('boolean', NS.xsdns),
45 }
46
47 @classmethod
48 - def auto(cls, node, value=None):
49 """
50 Automatically set the node's xsi:type attribute based on either I{value}'s
51 class or the class of the node's text. When I{value} is an unmapped class,
52 the default type (xs:any) is set.
53 @param node: An XML node
54 @type node: L{sax.element.Element}
55 @param value: An object that is or would be the node's text.
56 @type value: I{any}
57 @return: The specified node.
58 @rtype: L{sax.element.Element}
59 """
60 if value is None:
61 value = node.getText()
62 if isinstance(value, Object):
63 known = cls.known(value)
64 if known.name is None:
65 return node
66 tm = (known.name, known.namespace())
67 else:
68 tm = cls.types.get(value.__class__, cls.types.get(str))
69 cls.manual(node, *tm)
70 return node
71
72 @classmethod
73 - def manual(cls, node, tval, ns=None):
74 """
75 Set the node's xsi:type attribute based on either I{value}'s
76 class or the class of the node's text. Then adds the referenced
77 prefix(s) to the node's prefix mapping.
78 @param node: An XML node
79 @type node: L{sax.element.Element}
80 @param tval: The name of the schema type.
81 @type tval: str
82 @param ns: The XML namespace of I{tval}.
83 @type ns: (prefix, uri)
84 @return: The specified node.
85 @rtype: L{sax.element.Element}
86 """
87 xta = ':'.join((NS.xsins[0], 'type'))
88 node.addPrefix(NS.xsins[0], NS.xsins[1])
89 if ns is None:
90 node.set(xta, tval)
91 else:
92 ns = cls.genprefix(node, ns)
93 qname = ':'.join((ns[0], tval))
94 node.set(xta, qname)
95 node.addPrefix(ns[0], ns[1])
96 return node
97
98 @classmethod
100 """
101 Generate a prefix.
102 @param node: An XML node on which the prefix will be used.
103 @type node: L{sax.element.Element}
104 @param ns: A namespace needing an unique prefix.
105 @type ns: (prefix, uri)
106 @return: The I{ns} with a new prefix.
107 """
108 for n in range(1, 1024):
109 p = 'ns%d' % n
110 u = node.resolvePrefix(p, default=None)
111 if u is None or u == ns[1]:
112 return (p, ns[1])
113 raise Exception('auto prefix, exhausted')
114
115 @classmethod
117 try:
118 md = object.__metadata__
119 known = md.sxtype
120 return known
121 except:
122 pass
123