Adding support in xmlclass for timezone in datetime and for not paying attention to xml comments
authorlbessard
Fri, 26 Oct 2007 10:25:01 +0200
changeset 116 58b9b84e385f
parent 115 017a65259f07
child 117 bbe0697cf1ea
Adding support in xmlclass for timezone in datetime and for not paying attention to xml comments
PLCControler.py
TextViewer.py
examples/example.xml
xmlclass/xmlclass.py
--- a/PLCControler.py	Wed Oct 24 17:40:04 2007 +0200
+++ b/PLCControler.py	Fri Oct 26 10:25:01 2007 +0200
@@ -2115,14 +2115,18 @@
             xmlfile.close()
         
         self.Project = plcopen.project()
-        self.Project.loadXMLTree(tree.childNodes[0])
-        self.SetFilePath(filepath)
-        self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
-        self.Buffering = False
-        self.ElementsOpened = []
-        self.CurrentElementEditing = None
-        self.RefreshPouUsingTree()
-        self.RefreshBlockTypes()
+        for child in tree.childNodes:
+            if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project":
+                self.Project.loadXMLTree(child)
+                self.SetFilePath(filepath)
+                self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
+                self.Buffering = False
+                self.ElementsOpened = []
+                self.CurrentElementEditing = None
+                self.RefreshPouUsingTree()
+                self.RefreshBlockTypes()
+                return True
+        return False
 
     def SaveXMLFile(self, filepath = None):
         if not filepath and self.FilePath == "":
--- a/TextViewer.py	Wed Oct 24 17:40:04 2007 +0200
+++ b/TextViewer.py	Fri Oct 26 10:25:01 2007 +0200
@@ -153,7 +153,7 @@
         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
 
         self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER)
-        if window and controler:
+        if controler:
             self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
             self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER)
             self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
@@ -217,13 +217,15 @@
     # Buffer the last model state
     def RefreshBuffer(self):
         self.Controler.BufferProject()
-        self.ParentWindow.RefreshTitle()
-        self.ParentWindow.RefreshEditMenu()
+        if self.ParentWindow:
+            self.ParentWindow.RefreshTitle()
+            self.ParentWindow.RefreshEditMenu()
     
     def StartBuffering(self):
         self.Controler.StartBuffering()
-        self.ParentWindow.RefreshTitle()
-        self.ParentWindow.RefreshEditMenu()
+        if self.ParentWindow:
+            self.ParentWindow.RefreshTitle()
+            self.ParentWindow.RefreshEditMenu()
     
     def ResetBuffer(self):
         if self.CurrentAction != None:
--- a/examples/example.xml	Wed Oct 24 17:40:04 2007 +0200
+++ b/examples/example.xml	Fri Oct 26 10:25:01 2007 +0200
@@ -252,7 +252,7 @@
                 <relPosition y="60" x="2"/>
               </connectionPointOut>
             </leftPowerRail>
-            <coil localId="3" width="21" storage="none" height="15" negated="false">
+            <coil localId="3" width="21" height="15">
               <position y="72" x="265"/>
               <connectionPointIn>
                 <relPosition y="8" x="0"/>
@@ -276,7 +276,7 @@
                 </connection>
               </connectionPointIn>
             </rightPowerRail>
-            <contact localId="5" width="21" height="15" edge="none" negated="true">
+            <contact localId="5" width="21" height="15" negated="true">
               <position y="72" x="42"/>
               <connectionPointIn>
                 <relPosition y="8" x="0"/>
@@ -290,7 +290,7 @@
               </connectionPointOut>
               <variable>IN1</variable>
             </contact>
-            <contact localId="7" width="21" height="15" edge="none" negated="false">
+            <contact localId="7" width="21" height="15">
               <position y="72" x="174"/>
               <connectionPointIn>
                 <relPosition y="8" x="0"/>
@@ -310,7 +310,7 @@
               </connectionPointOut>
               <variable>IN2</variable>
             </contact>
-            <contact localId="8" width="21" height="15" edge="none" negated="false">
+            <contact localId="8" width="21" height="15">
               <position y="112" x="42"/>
               <connectionPointIn>
                 <relPosition y="8" x="0"/>
@@ -324,7 +324,7 @@
               </connectionPointOut>
               <variable>IN3</variable>
             </contact>
-            <contact localId="9" width="21" height="15" edge="none" negated="true">
+            <contact localId="9" width="21" height="15" negated="true">
               <position y="112" x="93"/>
               <connectionPointIn>
                 <relPosition y="8" x="0"/>
@@ -549,7 +549,7 @@
                     <relPosition y="64" x="2"/>
                   </connectionPointOut>
                 </leftPowerRail>
-                <contact localId="2" width="21" height="15" edge="none" negated="false">
+                <contact localId="2" width="21" height="15">
                   <position y="32" x="72"/>
                   <connectionPointIn>
                     <relPosition y="8" x="0"/>
@@ -563,7 +563,7 @@
                   </connectionPointOut>
                   <variable>IN2</variable>
                 </contact>
-                <contact localId="3" width="21" height="15" edge="rising" negated="false">
+                <contact localId="3" width="21" height="15" edge="rising">
                   <position y="76" x="72"/>
                   <connectionPointIn>
                     <relPosition y="8" x="0"/>
@@ -577,7 +577,7 @@
                   </connectionPointOut>
                   <variable>IN5</variable>
                 </contact>
-                <coil localId="4" width="21" storage="none" height="15" negated="true">
+                <coil localId="4" width="21" height="15" negated="true">
                   <position y="32" x="208"/>
                   <connectionPointIn>
                     <relPosition y="8" x="0"/>
@@ -645,7 +645,7 @@
                 <reference name="TR1"/>
               </condition>
             </transition>
-            <step localId="3" height="27" width="29" initialStep="false" name="Init">
+            <step localId="3" height="27" width="29" name="Init">
               <position y="129" x="91"/>
               <connectionPointIn>
                 <relPosition y="0" x="14"/>
@@ -698,7 +698,7 @@
                 </inline>
               </condition>
             </transition>
-            <step localId="6" height="27" width="48" initialStep="false" name="Step1">
+            <step localId="6" height="27" width="48" name="Step1">
               <position y="262" x="81"/>
               <connectionPointIn>
                 <relPosition y="0" x="24"/>
@@ -727,7 +727,7 @@
                 <reference name="TR2"/>
               </condition>
             </transition>
-            <step localId="8" height="27" width="48" initialStep="false" name="Step2">
+            <step localId="8" height="27" width="48" name="Step2">
               <position y="234" x="309"/>
               <connectionPointIn>
                 <relPosition y="0" x="24"/>
@@ -756,7 +756,7 @@
                 <reference name="TR4"/>
               </condition>
             </transition>
-            <step localId="10" height="27" width="48" initialStep="false" name="Step3">
+            <step localId="10" height="27" width="48" name="Step3">
               <position y="234" x="472"/>
               <connectionPointIn>
                 <relPosition y="0" x="24"/>
@@ -807,7 +807,7 @@
                   <position y="142" x="120"/>
                 </connection>
               </connectionPointIn>
-              <action qualifier="N">
+              <action>
                 <reference name="ACT1"/>
               </action>
             </actionBlock>
@@ -886,7 +886,7 @@
                   <position y="247" x="520"/>
                 </connection>
               </connectionPointIn>
-              <action indicator="IN5" qualifier="N">
+              <action indicator="IN5">
                 <reference name="ACT1"/>
               </action>
               <action qualifier="D" duration="T#10s">
@@ -914,7 +914,7 @@
                 <relPosition y="3" x="118"/>
               </connectionPointOut>
             </simultaneousDivergence>
-            <step localId="22" height="27" width="48" initialStep="false" name="Step4">
+            <step localId="22" height="27" width="48" name="Step4">
               <position y="262" x="199"/>
               <connectionPointIn>
                 <relPosition y="0" x="24"/>
--- a/xmlclass/xmlclass.py	Wed Oct 24 17:40:04 2007 +0200
+++ b/xmlclass/xmlclass.py	Fri Oct 26 10:25:01 2007 +0200
@@ -31,9 +31,30 @@
 """
 Regular expression models for extracting dates and times from a string
 """
-time_model = re.compile('([0-9]{2}):([0-9]{2}):([0-9]{2}(?:.[0-9]*)?)')
-date_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})')
-datetime_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})[ T]([0-9]{2}):([0-9]{2}):([0-9]{2}(?:.[0-9]*)?)')
+time_model = re.compile('([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]*)?)(?:Z)?')
+date_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})((?:[\-\+][0-9]{2}:[0-9]{2})|Z)?')
+datetime_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})[ T]([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]*)?)((?:[\-\+][0-9]{2}:[0-9]{2})|Z)?')
+
+class xml_timezone(tzinfo):
+
+    def SetOffset(self, offset):
+        if offset == "Z":
+            self.__offset = timedelta(minutes = 0)
+            self.__name = "UTC"
+        else:
+            sign = {"-" : -1, "+" : 1}[offset[0]]
+            hours, minutes = [int(val) for val in offset[1:].split(":")]
+            self.__offset = timedelta(minutes = sign * (hours * 60 + minutes))
+            self.__name = ""
+
+    def utcoffset(self, dt):
+        return self.__offset
+
+    def tzname(self, dt):
+        return self.__name
+
+    def dst(self, dt):
+        return ZERO
 
 XSD_INTEGER_TYPES = ["integer","nonPositiveInteger","negativeInteger","long",
     "int","short","byte","nonNegativeInteger","unsignedLong","unsignedInt",
@@ -109,7 +130,12 @@
     elif type_compute == "date":
         result = date_model.match(value)
         if result:
-            date_values = [int(v) for v in result.groups()]
+            values = result.groups()
+            date_values = [int(v) for v in values[:3]]
+            if values[3] is not None:
+                tz = xml_timezone()
+                tz.SetOffset(values[3])
+                date_values.append(tz)
             return date(*date_values)
         else:
             raise ValueError, "\"%s\" is not a valid date!"%value
@@ -120,6 +146,10 @@
             datetime_values = [int(v) for v in values[:5]]
             seconds = float(values[5])
             datetime_values.extend([int(seconds), int((seconds % 1) * 1000000)])
+            if values[6] is not None:
+                tz = xml_timezone()
+                tz.SetOffset(values[6])
+                datetime_values.append(tz)
             return datetime(*datetime_values)
         else:
             raise ValueError, "\"%s\" is not a valid datetime!"%value
@@ -638,6 +668,8 @@
             
             # Load the node childs if they are defined in the list
             for node in tree.childNodes:
+                if node.nodeType == node.COMMENT_NODE:
+                    continue
                 name = node.nodeName
                 # We make fun of #text elements
                 if name != "#text":