1.1 --- a/XSLForms/Fields.py Thu Dec 23 15:07:53 2004 +0000
1.2 +++ b/XSLForms/Fields.py Sun Dec 26 18:47:08 2004 +0000
1.3 @@ -1,11 +1,6 @@
1.4 #!/usr/bin/env python
1.5
1.6 """
1.7 -NOTE: Add support for multiple values from fields, perhaps using
1.8 -NOTE: the following notation:
1.9 -NOTE:
1.10 -NOTE: /package#1/categories#1/category#n/value
1.11 -
1.12 Classes which process field collections, producing instance
1.13 documents. Each field entry consists of a field name mapped
1.14 to a string value, where the field name may have the following
1.15 @@ -25,6 +20,11 @@
1.16 /zoo#1/cage#2/name
1.17 /zoo#1/funding#3/contributor#1/name
1.18
1.19 +Where multiple values can be collected for a given field, the
1.20 +following notation is employed:
1.21 +
1.22 + /package#1/categories#1/category##value
1.23 +
1.24 Some fields may contain the "=" string. This string is
1.25 reserved and all text following it is meant to specify a path
1.26 into a particular document. For example:
1.27 @@ -106,14 +106,35 @@
1.28
1.29 elif len(t) == 2:
1.30
1.31 - # Convert from one-based indexing (the position() function)
1.32 - # to zero-based indexing.
1.33 + # Convert from one-based indexing (the position()
1.34 + # function) to zero-based indexing.
1.35
1.36 name, index = t[0], int(t[1]) - 1
1.37 if index < 0:
1.38 break
1.39 node = self._enter_element(node, name, index)
1.40
1.41 + elif len(t) == 3 and t[1] == "":
1.42 +
1.43 + # Multivalued fields.
1.44 +
1.45 + if not self.values_are_lists:
1.46 + values = [value]
1.47 + else:
1.48 + values = value
1.49 +
1.50 + name = t[0]
1.51 + for index in range(0, len(values)):
1.52 + subnode = self._enter_element(node, name, index)
1.53 + subvalue = values[index]
1.54 +
1.55 + # Convert the value to Unicode if necessary.
1.56 +
1.57 + if type(subvalue) == type(""):
1.58 + subvalue = unicode(subvalue, encoding=self.encoding)
1.59 +
1.60 + subnode.setAttributeNS(EMPTY_NAMESPACE, t[2], subvalue)
1.61 +
1.62 def complete_selectors(self, selectors, fields, documents):
1.63
1.64 """
1.65 @@ -307,7 +328,8 @@
1.66 ("/zoo#1/cage#2/animal#2/property#2/value", "high"),
1.67 ("/zoo#1/funding#3/type", "private"),
1.68 ("/zoo#1/funding#3/contributor#1/name", "Animal Corporation"),
1.69 - ("/zoo#1/funding#3/contributor#1/amount", "543210.987")
1.70 + ("/zoo#1/funding#3/contributor#1/amount", "543210.987"),
1.71 + ("/zoo#1/funding#3/contributor#1/industry##type", "animals")
1.72 ]
1.73
1.74 import time
2.1 --- a/XSLForms/Output.py Thu Dec 23 15:07:53 2004 +0000
2.2 +++ b/XSLForms/Output.py Sun Dec 26 18:47:08 2004 +0000
2.3 @@ -16,7 +16,7 @@
2.4 libxml2.registerErrorHandler(quiet, None)
2.5 """
2.6
2.7 -def path_to_node(node, attribute_ref, name):
2.8 +def path_to_node(node, attribute_ref, name, multivalue=0):
2.9
2.10 """
2.11 Generate an XSLForms path to the given 'node', producing an attribute
2.12 @@ -32,6 +32,11 @@
2.13 required (and if a genuine attribute is found at the context node -
2.14 otherwise 'name' will be None and the context node will be treated like an
2.15 attribute).
2.16 +
2.17 + If 'multivalue' is true, produce an attribute reference using the given
2.18 + 'name' of the following form:
2.19 +
2.20 + /package#1/categories#1/category##name
2.21 """
2.22
2.23 l = []
2.24 @@ -40,9 +45,16 @@
2.25 node = node.parent
2.26 # Manually insert the attribute name if defined.
2.27 if attribute_ref:
2.28 + # A real attribute is referenced.
2.29 if name is not None:
2.30 l.insert(0, name)
2.31 + if multivalue:
2.32 + l.insert(0, Constants.pair_separator)
2.33 + l.insert(0, Constants.pair_separator)
2.34 + l.insert(0, node.name)
2.35 + node = node.parent
2.36 l.insert(0, Constants.path_separator)
2.37 + # Otherwise, treat the element name as an attribute name.
2.38 else:
2.39 l.insert(0, node.name)
2.40 l.insert(0, Constants.path_separator)
2.41 @@ -56,13 +68,15 @@
2.42 node = node.parent
2.43 return "".join(l)
2.44
2.45 -def path_to_context(context, attribute_ref):
2.46 +def path_to_context(context, attribute_ref, multivalue_name=None):
2.47
2.48 """
2.49 As a libxslt extension function, return a string containing the XSLForms
2.50 path to the 'context' node, using the special "this-name" variable to
2.51 complete the path if an attribute reference is required (as indicated by
2.52 - 'attribute_ref' being set to true).
2.53 + 'attribute_ref' being set to true). If 'multivalue_name' is set, produce a
2.54 + reference to a multivalued field using the given string as the attribute
2.55 + name.
2.56 """
2.57
2.58 pctxt = libxslt.xpathParserContext(_obj=context)
2.59 @@ -70,11 +84,16 @@
2.60 node = context.contextNode()
2.61 transform_context = context.transformContext()
2.62 name_var = transform_context.variableLookup("this-name", None)
2.63 - if name_var is not None:
2.64 + if multivalue_name is not None:
2.65 + name = multivalue_name
2.66 + multivalue = 1
2.67 + elif name_var is not None:
2.68 name = name_var[0].content
2.69 + multivalue = 0
2.70 else:
2.71 name = None
2.72 - return path_to_node(node, attribute_ref, name)
2.73 + multivalue = 0
2.74 + return path_to_node(node, attribute_ref, name, multivalue)
2.75
2.76 def this_position(context):
2.77 return path_to_context(context, 0)
2.78 @@ -82,7 +101,11 @@
2.79 def field_name(context):
2.80 return path_to_context(context, 1)
2.81
2.82 +def multi_field_name(context, multivalue_name):
2.83 + return path_to_context(context, 1, multivalue_name)
2.84 +
2.85 libxslt.registerExtModuleFunction("this-position", "http://www.boddie.org.uk/ns/xmltools/template", this_position)
2.86 libxslt.registerExtModuleFunction("field-name", "http://www.boddie.org.uk/ns/xmltools/template", field_name)
2.87 +libxslt.registerExtModuleFunction("multi-field-name", "http://www.boddie.org.uk/ns/xmltools/template", multi_field_name)
2.88
2.89 # vim: tabstop=4 expandtab shiftwidth=4