# HG changeset patch # User paulb # Date 1122056798 0 # Node ID 7e7d9dbcec620fdd8d93dfb675f98d49140de747 # Parent 28b1e6a409c8d9ad1c15d2f1260cd9bad856ca23 [project @ 2005-07-22 18:26:38 by paulb] Tidied up the function names and added some API documentation. Added child-element and child-attribute functions for coherent references to potentially non-existent nodes in the form data. diff -r 28b1e6a409c8 -r 7e7d9dbcec62 XSLForms/Output.py --- a/XSLForms/Output.py Fri Jul 22 00:05:16 2005 +0000 +++ b/XSLForms/Output.py Fri Jul 22 18:26:38 2005 +0000 @@ -124,28 +124,51 @@ node = libxml2dom.Node(libxml2mod.xmlXPathGetContextNode(context)) return path_to_node(node, attribute_ref, name, multivalue) -def this_position(context): - #print "this_position" +# Exposed extension functions. + +def this_element(context): + + """ + Exposed as {template:this-element()}. + Provides a reference to the current element in the form data structure. + """ + + #print "this_element" r = path_to_context(context, 0) return r.encode("utf-8") -def field_name(context): - #print "field_name" +def this_attribute(context): + + """ + Exposed as {template:this-attribute()}. + Provides a reference to the current attribute in the form data structure. + """ + + #print "this_attribute" r = path_to_context(context, 1) return r.encode("utf-8") -def multi_field_name(context, multivalue_name): - #print "multi_field_name" - r = path_to_context(context, 1, multivalue_name) - return r.encode("utf-8") +def new_attribute(context, name): -def new_field(context, name): - #print "new_field" + """ + Exposed as {template:new-attribute(name)}. + Provides a reference to a new attribute of the given 'name' on the current + element in the form data structure. + """ + + #print "new_attribute" r = path_to_context(context, 0) + "/" + name return r.encode("utf-8") -def other_field_names(context, nodes): - #print "other_field_names" +def other_elements(context, nodes): + + """ + Exposed as {template:other-elements(nodes)}. + Provides a reference to other elements in the form data structure according + to the specified 'nodes' parameter (an XPath expression in the template). + """ + + #print "other_elements" names = [] for node in nodes: name = path_to_node(libxml2dom.Node(node), 0, None, 0) @@ -154,6 +177,99 @@ r = ",".join(names) return r.encode("utf-8") +def list_attribute(context, element_name, attribute_name): + + """ + Exposed as {template:list-attribute(element_name, attribute_name)}. + Provides a reference to one or many elements of the given 'element_name' + found under the current element in the form data structure having + attributes with the given 'attribute_name'. + """ + + #print "list_attribute" + r = path_to_context(context, 0, (element_name, attribute_name)) + return r.encode("utf-8") + +def other_list_attributes(context, element_name, attribute_name, nodes): + + """ + Exposed as {template:other-list-attributes(element_name, attribute_name, nodes)}. + Provides a reference to other elements in the form data structure, found + under the specified 'nodes' (described using an XPath expression in the + template) having the given 'element_name' and bearing attributes of the + given 'attribute_name'. + """ + + #print "other_list_attributes" + names = [] + for node in nodes: + name = path_to_node(libxml2dom.Node(node), 0, (element_name, attribute_name), 1) + if name not in names: + names.append(name) + r = ",".join(names) + return r.encode("utf-8") + +def other_attributes(context, attribute_name, nodes): + + """ + Exposed as {template:other-attributes(name, nodes)}. + Provides a reference to attributes in the form data structure of the given + 'attribute_name' residing on the specified 'nodes' (described using an XPath + expression in the template). + """ + + #print "other_attributes" + # NOTE: Cannot directly reference attributes in the nodes list because + # NOTE: libxml2dom does not yet support parent element discovery on + # NOTE: attributes. + names = [] + for node in nodes: + name = path_to_node(libxml2dom.Node(node), 1, attribute_name, 0) + if name not in names: + names.append(name) + r = ",".join(names) + return r.encode("utf-8") + +def child_element(context, element_name, position, node_paths): + + """ + Exposed as {template:child-element(element_name, position, node_paths)}. + Provides relative paths to the specifed 'element_name', having the given + 'position' (1-based) under each element specified in 'node_paths' (provided + by calls to other extension functions in the template). For example: + + template:child-element('comment', 1, template:this-element()) -> '.../comment$1' + """ + + l = [] + for node_path in node_paths.split(","): + l.append(node_path + Constants.path_separator + element_name + + Constants.pair_separator + str(int(position))) + return ",".join(l).encode("utf-8") + +def child_attribute(context, attribute_name, node_paths): + + """ + Exposed as {template:child-attribute(attribute_name, node_paths)}. + Provides a relative path to the specifed 'attribute_name' for each element + specified in 'node_paths' (provided by calls to other extension functions in + the template). For example: + + template:child-attribute('value', template:this-element()) -> '.../value' + """ + + l = [] + for node_path in node_paths.split(","): + l.append(node_path + Constants.path_separator + attribute_name) + return ",".join(l).encode("utf-8") + +# Old implementations. + +def multi_field_name(context, multivalue_name): + #print "multi_field_name" + r = path_to_context(context, 1, multivalue_name) + return r.encode("utf-8") + def other_multi_field_names(context, multivalue_name, nodes): #print "other_multi_field_names" names = [] @@ -164,56 +280,31 @@ r = ",".join(names) return r.encode("utf-8") -# New implementations. - -def list_attribute(context, element_name, attribute_name): - #print "list_attribute" - r = path_to_context(context, 0, (element_name, attribute_name)) - return r.encode("utf-8") - -def other_list_attributes(context, element_name, attribute_name, nodes): - #print "other_list_attributes" - names = [] - for node in nodes: - name = path_to_node(libxml2dom.Node(node), 0, (element_name, attribute_name), 1) - if name not in names: - names.append(name) - r = ",".join(names) - return r.encode("utf-8") - -def other_attributes(context, attribute_name, nodes): - #print "other_attributes" - # NOTE: Cannot directly reference attributes in the nodes list because - # NOTE: libxml2dom does not yet support parent element discovery on - # NOTE: attributes. - names = [] - for node in nodes: - name = path_to_node(libxml2dom.Node(node), 1, attribute_name, 0) - if name not in names: - names.append(name) - r = ",".join(names) - return r.encode("utf-8") - # New functions. libxsltmod.xsltRegisterExtModuleFunction("list-attribute", "http://www.boddie.org.uk/ns/xmltools/template", list_attribute) libxsltmod.xsltRegisterExtModuleFunction("other-list-attributes", "http://www.boddie.org.uk/ns/xmltools/template", other_list_attributes) libxsltmod.xsltRegisterExtModuleFunction("other-attributes", "http://www.boddie.org.uk/ns/xmltools/template", other_attributes) +libxsltmod.xsltRegisterExtModuleFunction("child-element", "http://www.boddie.org.uk/ns/xmltools/template", child_element) +libxsltmod.xsltRegisterExtModuleFunction("child-attribute", "http://www.boddie.org.uk/ns/xmltools/template", child_attribute) # New names. -libxsltmod.xsltRegisterExtModuleFunction("this-element", "http://www.boddie.org.uk/ns/xmltools/template", this_position) -libxsltmod.xsltRegisterExtModuleFunction("this-attribute", "http://www.boddie.org.uk/ns/xmltools/template", field_name) -libxsltmod.xsltRegisterExtModuleFunction("new-attribute", "http://www.boddie.org.uk/ns/xmltools/template", new_field) -libxsltmod.xsltRegisterExtModuleFunction("other-elements", "http://www.boddie.org.uk/ns/xmltools/template", other_field_names) +libxsltmod.xsltRegisterExtModuleFunction("this-element", "http://www.boddie.org.uk/ns/xmltools/template", this_element) +libxsltmod.xsltRegisterExtModuleFunction("this-attribute", "http://www.boddie.org.uk/ns/xmltools/template", this_attribute) +libxsltmod.xsltRegisterExtModuleFunction("new-attribute", "http://www.boddie.org.uk/ns/xmltools/template", new_attribute) +libxsltmod.xsltRegisterExtModuleFunction("other-elements", "http://www.boddie.org.uk/ns/xmltools/template", other_elements) # Old names. -libxsltmod.xsltRegisterExtModuleFunction("this-position", "http://www.boddie.org.uk/ns/xmltools/template", this_position) -libxsltmod.xsltRegisterExtModuleFunction("field-name", "http://www.boddie.org.uk/ns/xmltools/template", field_name) +libxsltmod.xsltRegisterExtModuleFunction("this-position", "http://www.boddie.org.uk/ns/xmltools/template", this_element) +libxsltmod.xsltRegisterExtModuleFunction("field-name", "http://www.boddie.org.uk/ns/xmltools/template", this_attribute) +libxsltmod.xsltRegisterExtModuleFunction("new-field", "http://www.boddie.org.uk/ns/xmltools/template", new_attribute) +libxsltmod.xsltRegisterExtModuleFunction("other-field-names", "http://www.boddie.org.uk/ns/xmltools/template", other_elements) + +# Old functions. + libxsltmod.xsltRegisterExtModuleFunction("multi-field-name", "http://www.boddie.org.uk/ns/xmltools/template", multi_field_name) -libxsltmod.xsltRegisterExtModuleFunction("new-field", "http://www.boddie.org.uk/ns/xmltools/template", new_field) -libxsltmod.xsltRegisterExtModuleFunction("other-field-names", "http://www.boddie.org.uk/ns/xmltools/template", other_field_names) libxsltmod.xsltRegisterExtModuleFunction("other-multi-field-names", "http://www.boddie.org.uk/ns/xmltools/template", other_multi_field_names) def get_field_name(field_or_multi_name):