| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 # -*- test-case-name: twisted.web.test.test_woven -*- |  | 
| 2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. |  | 
| 3 # See LICENSE for details. |  | 
| 4 |  | 
| 5 # |  | 
| 6 |  | 
| 7 from __future__ import nested_scopes |  | 
| 8 |  | 
| 9 from twisted.web import microdom |  | 
| 10 from microdom import getElementsByTagName, escape, unescape |  | 
| 11 |  | 
| 12 try: |  | 
| 13     import cStringIO as StringIO |  | 
| 14 except ImportError: |  | 
| 15     import StringIO |  | 
| 16 |  | 
| 17 class NodeLookupError(Exception): pass |  | 
| 18 |  | 
| 19 |  | 
| 20 def substitute(request, node, subs): |  | 
| 21     """ |  | 
| 22     Look through the given node's children for strings, and |  | 
| 23     attempt to do string substitution with the given parameter. |  | 
| 24     """ |  | 
| 25     for child in node.childNodes: |  | 
| 26         if hasattr(child, 'nodeValue') and child.nodeValue: |  | 
| 27             child.replaceData(0, len(child.nodeValue), child.nodeValue % subs) |  | 
| 28         substitute(request, child, subs) |  | 
| 29 |  | 
| 30 def _get(node, nodeId, nodeAttrs=('id','class','model','pattern')): |  | 
| 31     """ |  | 
| 32     (internal) Get a node with the specified C{nodeId} as any of the C{class}, |  | 
| 33     C{id} or C{pattern} attributes. |  | 
| 34     """ |  | 
| 35 |  | 
| 36     if hasattr(node, 'hasAttributes') and node.hasAttributes(): |  | 
| 37         for nodeAttr in nodeAttrs: |  | 
| 38             if (str (node.getAttribute(nodeAttr)) == nodeId): |  | 
| 39                 return node |  | 
| 40     if node.hasChildNodes(): |  | 
| 41         if hasattr(node.childNodes, 'length'): |  | 
| 42             length = node.childNodes.length |  | 
| 43         else: |  | 
| 44             length = len(node.childNodes) |  | 
| 45         for childNum in range(length): |  | 
| 46             result = _get(node.childNodes[childNum], nodeId) |  | 
| 47             if result: return result |  | 
| 48 |  | 
| 49 def get(node, nodeId): |  | 
| 50     """ |  | 
| 51     Get a node with the specified C{nodeId} as any of the C{class}, |  | 
| 52     C{id} or C{pattern} attributes. If there is no such node, raise |  | 
| 53     L{NodeLookupError}. |  | 
| 54     """ |  | 
| 55     result = _get(node, nodeId) |  | 
| 56     if result: return result |  | 
| 57     raise NodeLookupError, nodeId |  | 
| 58 |  | 
| 59 def getIfExists(node, nodeId): |  | 
| 60     """ |  | 
| 61     Get a node with the specified C{nodeId} as any of the C{class}, |  | 
| 62     C{id} or C{pattern} attributes.  If there is no such node, return |  | 
| 63     C{None}. |  | 
| 64     """ |  | 
| 65     return _get(node, nodeId) |  | 
| 66 |  | 
| 67 def getAndClear(node, nodeId): |  | 
| 68     """Get a node with the specified C{nodeId} as any of the C{class}, |  | 
| 69     C{id} or C{pattern} attributes. If there is no such node, raise |  | 
| 70     L{NodeLookupError}. Remove all child nodes before returning. |  | 
| 71     """ |  | 
| 72     result = get(node, nodeId) |  | 
| 73     if result: |  | 
| 74         clearNode(result) |  | 
| 75     return result |  | 
| 76 |  | 
| 77 def clearNode(node): |  | 
| 78     """ |  | 
| 79     Remove all children from the given node. |  | 
| 80     """ |  | 
| 81     node.childNodes[:] = [] |  | 
| 82 |  | 
| 83 def locateNodes(nodeList, key, value, noNesting=1): |  | 
| 84     """ |  | 
| 85     Find subnodes in the given node where the given attribute |  | 
| 86     has the given value. |  | 
| 87     """ |  | 
| 88     returnList = [] |  | 
| 89     if not isinstance(nodeList, type([])): |  | 
| 90         return locateNodes(nodeList.childNodes, key, value, noNesting) |  | 
| 91     for childNode in nodeList: |  | 
| 92         if not hasattr(childNode, 'getAttribute'): |  | 
| 93             continue |  | 
| 94         if str(childNode.getAttribute(key)) == value: |  | 
| 95             returnList.append(childNode) |  | 
| 96             if noNesting: |  | 
| 97                 continue |  | 
| 98         returnList.extend(locateNodes(childNode, key, value, noNesting)) |  | 
| 99     return returnList |  | 
| 100 |  | 
| 101 def superSetAttribute(node, key, value): |  | 
| 102     if not hasattr(node, 'setAttribute'): return |  | 
| 103     node.setAttribute(key, value) |  | 
| 104     if node.hasChildNodes(): |  | 
| 105         for child in node.childNodes: |  | 
| 106             superSetAttribute(child, key, value) |  | 
| 107 |  | 
| 108 def superPrependAttribute(node, key, value): |  | 
| 109     if not hasattr(node, 'setAttribute'): return |  | 
| 110     old = node.getAttribute(key) |  | 
| 111     if old: |  | 
| 112         node.setAttribute(key, value+'/'+old) |  | 
| 113     else: |  | 
| 114         node.setAttribute(key, value) |  | 
| 115     if node.hasChildNodes(): |  | 
| 116         for child in node.childNodes: |  | 
| 117             superPrependAttribute(child, key, value) |  | 
| 118 |  | 
| 119 def superAppendAttribute(node, key, value): |  | 
| 120     if not hasattr(node, 'setAttribute'): return |  | 
| 121     old = node.getAttribute(key) |  | 
| 122     if old: |  | 
| 123         node.setAttribute(key, old + '/' + value) |  | 
| 124     else: |  | 
| 125         node.setAttribute(key, value) |  | 
| 126     if node.hasChildNodes(): |  | 
| 127         for child in node.childNodes: |  | 
| 128             superAppendAttribute(child, key, value) |  | 
| 129 |  | 
| 130 def gatherTextNodes(iNode, dounescape=0, joinWith=""): |  | 
| 131     """Visit each child node and collect its text data, if any, into a string. |  | 
| 132 For example:: |  | 
| 133     >>> doc=microdom.parseString('<a>1<b>2<c>3</c>4</b></a>') |  | 
| 134     >>> gatherTextNodes(doc.documentElement) |  | 
| 135     '1234' |  | 
| 136 With dounescape=1, also convert entities back into normal characters. |  | 
| 137 @return: the gathered nodes as a single string |  | 
| 138 @rtype: str |  | 
| 139 """ |  | 
| 140     gathered=[] |  | 
| 141     gathered_append=gathered.append |  | 
| 142     slice=[iNode] |  | 
| 143     while len(slice)>0: |  | 
| 144         c=slice.pop(0) |  | 
| 145         if hasattr(c, 'nodeValue') and c.nodeValue is not None: |  | 
| 146             if dounescape: |  | 
| 147                 val=unescape(c.nodeValue) |  | 
| 148             else: |  | 
| 149                 val=c.nodeValue |  | 
| 150             gathered_append(val) |  | 
| 151         slice[:0]=c.childNodes |  | 
| 152     return joinWith.join(gathered) |  | 
| 153 |  | 
| 154 class RawText(microdom.Text): |  | 
| 155     """This is an evil and horrible speed hack. Basically, if you have a big |  | 
| 156     chunk of XML that you want to insert into the DOM, but you don't want to |  | 
| 157     incur the cost of parsing it, you can construct one of these and insert it |  | 
| 158     into the DOM. This will most certainly only work with microdom as the API |  | 
| 159     for converting nodes to xml is different in every DOM implementation. |  | 
| 160 |  | 
| 161     This could be improved by making this class a Lazy parser, so if you |  | 
| 162     inserted this into the DOM and then later actually tried to mutate this |  | 
| 163     node, it would be parsed then. |  | 
| 164     """ |  | 
| 165 |  | 
| 166     def writexml(self, writer, indent="", addindent="", newl="", strip=0, nspref
     ixes=None, namespace=None): |  | 
| 167         writer.write("%s%s%s" % (indent, self.data, newl)) |  | 
| 168 |  | 
| 169 def findNodes(parent, matcher, accum=None): |  | 
| 170     if accum is None: |  | 
| 171         accum = [] |  | 
| 172     if not parent.hasChildNodes(): |  | 
| 173         return accum |  | 
| 174     for child in parent.childNodes: |  | 
| 175         # print child, child.nodeType, child.nodeName |  | 
| 176         if matcher(child): |  | 
| 177             accum.append(child) |  | 
| 178         findNodes(child, matcher, accum) |  | 
| 179     return accum |  | 
| 180 |  | 
| 181 |  | 
| 182 def findNodesShallowOnMatch(parent, matcher, recurseMatcher, accum=None): |  | 
| 183     if accum is None: |  | 
| 184         accum = [] |  | 
| 185     if not parent.hasChildNodes(): |  | 
| 186         return accum |  | 
| 187     for child in parent.childNodes: |  | 
| 188         # print child, child.nodeType, child.nodeName |  | 
| 189         if matcher(child): |  | 
| 190             accum.append(child) |  | 
| 191         if recurseMatcher(child): |  | 
| 192             findNodesShallowOnMatch(child, matcher, recurseMatcher, accum) |  | 
| 193     return accum |  | 
| 194 |  | 
| 195 def findNodesShallow(parent, matcher, accum=None): |  | 
| 196     if accum is None: |  | 
| 197         accum = [] |  | 
| 198     if not parent.hasChildNodes(): |  | 
| 199         return accum |  | 
| 200     for child in parent.childNodes: |  | 
| 201         if matcher(child): |  | 
| 202             accum.append(child) |  | 
| 203         else: |  | 
| 204             findNodes(child, matcher, accum) |  | 
| 205     return accum |  | 
| 206 |  | 
| 207 |  | 
| 208 def findElementsWithAttributeShallow(parent, attribute): |  | 
| 209     return findNodesShallow(parent, |  | 
| 210         lambda n: isinstance(n, microdom.Element) and |  | 
| 211             n.hasAttribute(attribute)) |  | 
| 212 |  | 
| 213 |  | 
| 214 def findElements(parent, matcher): |  | 
| 215     return findNodes( |  | 
| 216         parent, |  | 
| 217         lambda n, matcher=matcher: isinstance(n, microdom.Element) and |  | 
| 218                                    matcher(n)) |  | 
| 219 |  | 
| 220 def findElementsWithAttribute(parent, attribute, value=None): |  | 
| 221     if value: |  | 
| 222         return findElements( |  | 
| 223             parent, |  | 
| 224             lambda n, attribute=attribute, value=value: |  | 
| 225               n.hasAttribute(attribute) and n.getAttribute(attribute) == value) |  | 
| 226     else: |  | 
| 227         return findElements( |  | 
| 228             parent, |  | 
| 229             lambda n, attribute=attribute: n.hasAttribute(attribute)) |  | 
| 230 |  | 
| 231 |  | 
| 232 def findNodesNamed(parent, name): |  | 
| 233     return findNodes(parent, lambda n, name=name: n.nodeName == name) |  | 
| 234 |  | 
| 235 |  | 
| 236 def writeNodeData(node, oldio): |  | 
| 237     for subnode in node.childNodes: |  | 
| 238         if hasattr(subnode, 'data'): |  | 
| 239             oldio.write(str(subnode.data)) |  | 
| 240         else: |  | 
| 241             writeNodeData(subnode, oldio) |  | 
| 242 |  | 
| 243 |  | 
| 244 def getNodeText(node): |  | 
| 245     oldio = StringIO.StringIO() |  | 
| 246     writeNodeData(node, oldio) |  | 
| 247     return oldio.getvalue() |  | 
| 248 |  | 
| 249 def getParents(node): |  | 
| 250     l = [] |  | 
| 251     while node: |  | 
| 252         l.append(node) |  | 
| 253         node = node.parentNode |  | 
| 254     return l |  | 
| 255 |  | 
| 256 def namedChildren(parent, nodeName): |  | 
| 257     """namedChildren(parent, nodeName) -> children (not descendants) of parent |  | 
| 258     that have tagName == nodeName |  | 
| 259     """ |  | 
| 260     return [n for n in parent.childNodes if getattr(n, 'tagName', '')==nodeName] |  | 
| OLD | NEW | 
|---|