Fixed / overloading when enabling true division.
[tx] / nodes_misc.py
1 # -*- coding:utf-8 -*-
2
3 # Nodes misc
4 # Copyright (C) 2005  Frédéric Jolliton <frederic@jolliton.com>
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 from misc import NotReached, typeOf
21 from nodes import *
22
23 def isText( item ) :
24
25         '''Test if 'item' is a Text node.'''
26
27         return isinstance( item , Text )
28
29 def isComment( item ) :
30
31         '''Test if 'item' is a Comment node.'''
32
33         return isinstance( item , Comment )
34
35 def makeElementTest( name ) :
36
37         '''Return a function taking a item as parameter and
38         testing if it's a Element with the name 'name'.'''
39
40         def fun( item ) :
41                 return isinstance( item , Element ) and item.name == name
42         return fun
43
44 def findPosition( siblings , node , test ) :
45
46         '''Return index of the node 'node' inside the list of 'siblings'
47         who match the 'test' predicate. Also return a boolean to specify
48         if there was more than 1 node matching the 'test' predicate.'''
49
50         pos = 0
51         found = 0
52         for item in siblings :
53                 if test( item ) :
54                         pos += 1
55                         if found :
56                                 break
57                 if item is node :
58                         assert pos , 'node is not matched by predicate test'
59                         found = pos
60         assert found , 'node not found in siblings list'
61         return found , ( found <= 1 and pos <= 1 )
62
63 def nodeToXpath( node ) :
64
65         '''Return a XPath expression that point to the node 'node'.'''
66
67         if isinstance( node , Node ) :
68                 root = node.root
69                 steps = []
70                 while True :
71                         parent = node.parent
72                         if not parent :
73                                 break
74                         if isinstance( node , ( Text , Element , Comment ) ) :
75                                 if isinstance( node , Text ) :
76                                         test = isText
77                                         step = 'text()'
78                                 elif isinstance( node , Element ) :
79                                         test = makeElementTest( node.name )
80                                         step = node.name
81                                 elif isinstance( node , Comment ) :
82                                         test = isComment
83                                         step = 'comment()'
84                                 else :
85                                         raise NotReached
86                                 pos , alone = findPosition( parent.children , node , test )
87                                 if not alone :
88                                         step += '[%d]' % pos
89                                 steps.append( step )
90                         elif isinstance( node , Attribute ) :
91                                 steps.append( '@%s' % node.name )
92                         else :
93                                 assert False , 'Unexpected node type %r' % typeOf( node )
94                         node = parent
95                 result = '/'.join( reversed( steps ) )
96                 if node == node.root :
97                         result = '/' + result
98                 return result
99
100 # Local Variables:
101 # tab-width: 4
102 # python-indent: 4
103 # End: