2.1 --- a/XSLForms/Output.py Fri Jun 20 23:27:43 2008 +0000
2.2 +++ b/XSLForms/Output.py Sat Oct 11 23:11:02 2008 +0200
2.3 @@ -3,7 +3,7 @@
2.4 """
2.5 XSL-based form templating.
2.6
2.7 -Copyright (C) 2005, 2007 Paul Boddie <paul@boddie.org.uk>
2.8 +Copyright (C) 2005, 2007, 2008 Paul Boddie <paul@boddie.org.uk>
2.9
2.10 This program is free software; you can redistribute it and/or modify it under
2.11 the terms of the GNU Lesser General Public License as published by the Free
2.12 @@ -34,7 +34,7 @@
2.13
2.14 libxml2_encoding = "utf-8"
2.15
2.16 -def path_to_node(node, attribute_ref, name, multivalue=0):
2.17 +def path_to_node(node, attribute_ref=None, name=None, multivalue=0):
2.18
2.19 """
2.20 Generate an XSLForms path to the given 'node', producing an attribute
2.21 @@ -63,12 +63,27 @@
2.22 """
2.23
2.24 l = []
2.25 - # Skip attribute reference.
2.26 +
2.27 + # Skip attribute references.
2.28 + # Where a node reference has been requested, initialise the name and
2.29 + # attribute reference settings.
2.30 +
2.31 if node.nodeType == node.ATTRIBUTE_NODE:
2.32 + if name is None:
2.33 + name = node.localName
2.34 + if attribute_ref is None:
2.35 + attribute_ref = 1
2.36 node = node.parentNode
2.37 + else:
2.38 + if attribute_ref is None:
2.39 + attribute_ref = 0
2.40 +
2.41 # Manually insert the attribute name if defined.
2.42 +
2.43 if attribute_ref:
2.44 +
2.45 # A real attribute is referenced.
2.46 +
2.47 if name is not None:
2.48 l.insert(0, name)
2.49 if multivalue:
2.50 @@ -76,13 +91,17 @@
2.51 l.insert(0, node.nodeName)
2.52 node = node.parentNode
2.53 l.insert(0, Constants.path_separator)
2.54 +
2.55 # Otherwise, treat the element name as an attribute name.
2.56 # NOTE: Not sure how useful this is.
2.57 +
2.58 else:
2.59 l.insert(0, node.nodeName)
2.60 l.insert(0, Constants.path_separator)
2.61 node = node.parentNode
2.62 +
2.63 # Otherwise insert any multivalue references (eg. list-attribute).
2.64 +
2.65 elif multivalue:
2.66 element_name, attribute_name = name
2.67 l.insert(0, attribute_name)
2.68 @@ -91,12 +110,14 @@
2.69 l.insert(0, Constants.path_separator)
2.70
2.71 # Element references.
2.72 +
2.73 while node is not None and node.nodeType != node.DOCUMENT_NODE:
2.74 l.insert(0, str(int(node.xpath("count(preceding-sibling::*) + 1"))))
2.75 l.insert(0, Constants.pair_separator)
2.76 l.insert(0, node.nodeName)
2.77 l.insert(0, Constants.path_separator)
2.78 node = node.parentNode
2.79 +
2.80 return "".join(l)
2.81
2.82 def path_to_context(context, attribute_ref, multivalue_name=None):
2.83 @@ -234,9 +255,9 @@
2.84
2.85 #print "other_attributes"
2.86 attribute_name = unicode(attribute_name, libxml2_encoding)
2.87 - # NOTE: Cannot directly reference attributes in the nodes list because
2.88 - # NOTE: libxml2dom does not yet support parent element discovery on
2.89 - # NOTE: attributes.
2.90 + # NOTE: Could not directly reference attributes in the nodes list because
2.91 + # NOTE: libxml2dom did not yet support parent element discovery on
2.92 + # NOTE: attributes. The nodes function below remedies this.
2.93 names = []
2.94 for node in nodes:
2.95 name = path_to_node(libxml2dom.Node(node), 1, attribute_name, 0)
2.96 @@ -245,6 +266,23 @@
2.97 r = ",".join(names)
2.98 return r.encode(libxml2_encoding)
2.99
2.100 +def nodes(context, nodes):
2.101 +
2.102 + """
2.103 + Exposed as {template:nodes(nodes)}.
2.104 +
2.105 + Provides a reference to 'nodes' in the form data structure, described using
2.106 + an XPath expression in the template.
2.107 + """
2.108 +
2.109 + names = []
2.110 + for node in nodes:
2.111 + name = path_to_node(libxml2dom.Node(node))
2.112 + if name not in names:
2.113 + names.append(name)
2.114 + r = ",".join(names)
2.115 + return r.encode(libxml2_encoding)
2.116 +
2.117 def child_element(context, element_name, position, node_paths):
2.118
2.119 """
2.120 @@ -493,6 +531,7 @@
2.121 libxsltmod.xsltRegisterExtModuleFunction("child-element", "http://www.boddie.org.uk/ns/xmltools/template", child_element)
2.122 libxsltmod.xsltRegisterExtModuleFunction("child-attribute", "http://www.boddie.org.uk/ns/xmltools/template", child_attribute)
2.123 libxsltmod.xsltRegisterExtModuleFunction("selector-name", "http://www.boddie.org.uk/ns/xmltools/template", selector_name)
2.124 +libxsltmod.xsltRegisterExtModuleFunction("nodes", "http://www.boddie.org.uk/ns/xmltools/template", nodes)
2.125
2.126 # New names.
2.127