1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/XSLForms/Constants.py Tue Dec 21 19:23:16 2004 +0000
1.3 @@ -0,0 +1,9 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"Constants for XSLForms."
1.7 +
1.8 +path_separator = "/"
1.9 +pair_separator = "#"
1.10 +selector_indicator = "="
1.11 +
1.12 +# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/XSLForms/Fields.py Tue Dec 21 00:46:33 2004 +0000
2.2 +++ b/XSLForms/Fields.py Tue Dec 21 19:23:16 2004 +0000
2.3 @@ -27,6 +27,7 @@
2.4 _action_add_animal=/zoo#1/cage#2
2.5 """
2.6
2.7 +import Constants
2.8 import libxml2dom
2.9 from xml.dom import EMPTY_NAMESPACE
2.10
2.11 @@ -40,10 +41,6 @@
2.12 instance documents.
2.13 """
2.14
2.15 - _path_separator = "/"
2.16 - _pair_separator = "#"
2.17 - _selector_indicator = "="
2.18 -
2.19 def __init__(self, encoding="utf-8", values_are_lists=0):
2.20
2.21 """
2.22 @@ -69,7 +66,7 @@
2.23
2.24 # Ignore selectors.
2.25
2.26 - if field.find(self._selector_indicator) != -1:
2.27 + if field.find(Constants.selector_indicator) != -1:
2.28 continue
2.29
2.30 model_name, components = self._get_model_name_and_components(field)
2.31 @@ -96,7 +93,7 @@
2.32 # Traverse the components within the instance.
2.33
2.34 for component in components:
2.35 - t = component.split(self._pair_separator)
2.36 + t = component.split(Constants.pair_separator)
2.37 if len(t) == 1:
2.38 node.setAttributeNS(EMPTY_NAMESPACE, t[0], value)
2.39 break
2.40 @@ -123,7 +120,7 @@
2.41
2.42 # Process selectors only.
2.43
2.44 - selector_components = field.split(self._selector_indicator)
2.45 + selector_components = field.split(Constants.selector_indicator)
2.46 if len(selector_components) < 2:
2.47 continue
2.48
2.49 @@ -132,7 +129,7 @@
2.50 # but the separator really should not exist in the path.
2.51
2.52 selector_name = selector_components[0]
2.53 - path = self._selector_indicator.join(selector_components[1:])
2.54 + path = Constants.selector_indicator.join(selector_components[1:])
2.55
2.56 model_name, components = self._get_model_name_and_components(path)
2.57 if model_name is None:
2.58 @@ -149,7 +146,7 @@
2.59 # selected.
2.60
2.61 for component in components:
2.62 - t = component.split(self._pair_separator)
2.63 + t = component.split(Constants.pair_separator)
2.64 if len(t) == 1:
2.65
2.66 # Select attribute.
2.67 @@ -210,7 +207,7 @@
2.68 # Example: /name1#n1/name2#n2/name3
2.69 # Expected: ['', 'name1#n1', 'name2#n2', 'name3']
2.70
2.71 - components = field.split(self._path_separator)
2.72 + components = field.split(Constants.path_separator)
2.73 if len(components) < 2:
2.74 return None, None
2.75
2.76 @@ -218,7 +215,7 @@
2.77 # specification.
2.78 # Expected: ['name1', 'n1']
2.79
2.80 - model_name_and_index = components[1].split(self._pair_separator)
2.81 + model_name_and_index = components[1].split(Constants.pair_separator)
2.82 if len(model_name_and_index) != 2:
2.83 return None, None
2.84
3.1 --- a/XSLForms/Output.py Tue Dec 21 00:46:33 2004 +0000
3.2 +++ b/XSLForms/Output.py Tue Dec 21 19:23:16 2004 +0000
3.3 @@ -4,6 +4,7 @@
3.4 XSL-based form templating.
3.5 """
3.6
3.7 +import Constants
3.8 import libxslt
3.9
3.10 """
3.11 @@ -15,12 +16,22 @@
3.12 libxml2.registerErrorHandler(quiet, None)
3.13 """
3.14
3.15 -def path_to_node(node, name):
3.16 +def path_to_node(node, attribute_ref, name):
3.17
3.18 """
3.19 - Generate an XSLForms path to the given 'node', using the given 'name' to
3.20 - complete the path if an attribute reference is required (otherwise 'name'
3.21 - will be None).
3.22 + Generate an XSLForms path to the given 'node', producing an attribute
3.23 + reference if 'attribute_ref' is true; for example:
3.24 +
3.25 + /package#1/discriminators#5/discriminator#1/category
3.26 +
3.27 + Otherwise an element reference is produced; for example:
3.28 +
3.29 + /package#1/discriminators#5/discriminator#1
3.30 +
3.31 + Use the given 'name' to complete the path if an attribute reference is
3.32 + required (and if a genuine attribute is found at the context node -
3.33 + otherwise 'name' will be None and the context node will be treated like an
3.34 + attribute).
3.35 """
3.36
3.37 l = []
3.38 @@ -28,24 +39,30 @@
3.39 if node.type == "attribute":
3.40 node = node.parent
3.41 # Manually insert the attribute name if defined.
3.42 - if name is not None:
3.43 - l.insert(0, name)
3.44 - l.insert(0, "/")
3.45 + if attribute_ref:
3.46 + if name is not None:
3.47 + l.insert(0, name)
3.48 + l.insert(0, Constants.path_separator)
3.49 + else:
3.50 + l.insert(0, node.name)
3.51 + l.insert(0, Constants.path_separator)
3.52 + node = node.parent
3.53 # Element references.
3.54 while node is not None and node.type != "document_xml":
3.55 l.insert(0, str(int(node.xpathEval("count(preceding-sibling::*) + 1"))))
3.56 - l.insert(0, "#")
3.57 + l.insert(0, Constants.pair_separator)
3.58 l.insert(0, node.name)
3.59 - l.insert(0, "/")
3.60 + l.insert(0, Constants.path_separator)
3.61 node = node.parent
3.62 return "".join(l)
3.63
3.64 -def this_position(context):
3.65 +def path_to_context(context, attribute_ref):
3.66
3.67 """
3.68 As a libxslt extension function, return a string containing the XSLForms
3.69 path to the 'context' node, using the special "this-name" variable to
3.70 - complete the path if an attribute reference is required.
3.71 + complete the path if an attribute reference is required (as indicated by
3.72 + 'attribute_ref' being set to true).
3.73 """
3.74
3.75 pctxt = libxslt.xpathParserContext(_obj=context)
3.76 @@ -57,8 +74,15 @@
3.77 name = name_var[0].content
3.78 else:
3.79 name = None
3.80 - return path_to_node(node, name)
3.81 + return path_to_node(node, attribute_ref, name)
3.82 +
3.83 +def this_position(context):
3.84 + return path_to_context(context, 0)
3.85 +
3.86 +def field_name(context):
3.87 + return path_to_context(context, 1)
3.88
3.89 libxslt.registerExtModuleFunction("this-position", "http://www.boddie.org.uk/ns/xmltools/template", this_position)
3.90 +libxslt.registerExtModuleFunction("field-name", "http://www.boddie.org.uk/ns/xmltools/template", field_name)
3.91
3.92 # vim: tabstop=4 expandtab shiftwidth=4