[GRASS-SVN] r61579 - in sandbox/krejcmat/src: . templates

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 10 22:43:51 PDT 2014


Author: krejcmat
Date: 2014-08-10 22:43:51 -0700 (Sun, 10 Aug 2014)
New Revision: 61579

Added:
   sandbox/krejcmat/src/templates/basicTemplate.xml
   sandbox/krejcmat/src/templates/inspireTemplate.xml
Removed:
   sandbox/krejcmat/src/templates/grassGRASSTemplateFinal.xml
   sandbox/krejcmat/src/templates/grassInspireTemplateFinal.xml
Modified:
   sandbox/krejcmat/src/g.gui.metadata.py
   sandbox/krejcmat/src/jinjainfo.py
   sandbox/krejcmat/src/mdgrass.py
   sandbox/krejcmat/src/mdutil.py
   sandbox/krejcmat/src/r.info.iso.py
   sandbox/krejcmat/src/v.info.iso.py
Log:
last up g.gui.metadata

Modified: sandbox/krejcmat/src/g.gui.metadata.py
===================================================================
--- sandbox/krejcmat/src/g.gui.metadata.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/g.gui.metadata.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,258 +1,211 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
 """
-MODULE:    g.gui.metadata
+ at module  g.gui.metadata
+ at brief   GUI components of metadata editor
 
-AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+Classes:
+ - g.gui.metadata::MdMainFrame
+ - g.gui.metadata::MdDataCatalog
+ - g.gui.metadata::NotebookRight
+ - g.gui.metadata::MDHelp
+ - g.gui.metadata::TreeBrowser
+ - g.gui.metadata::MdValidator
+ - g.gui.metadata::MdEditConfigPanel
+ - g.gui.metadata::MdToolbar
 
-PURPOSE:   Module for editing metadata based on EN ISO 19115 and EN ISO 19119
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
 
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
-
-           This program is free software under the GNU General Public
-           License (>=v2). Read the file COPYING that comes with GRASS
-           for details.
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
 
-
-
 import wx
-from wx.lib.buttons  import ThemedGenBitmapTextButton    as BitmapBtnTxt
-from wx              import SplitterWindow, EVT_BUTTON
-from wx.lib.pubsub   import setupkwargs,pub
-from editor3         import MdMainEditor
+from wx.lib.buttons import ThemedGenBitmapTextButton as BitmapBtnTxt
+from wx import SplitterWindow, EVT_BUTTON
+from wx.lib.pubsub import setupkwargs, pub
+from editor import MdMainEditor
 
-import glob,os,sys
-import mdgrass,mdutil
-from lxml            import etree
+import glob
+import os
+import sys
+import mdgrass
+import mdutil
+from lxml import etree
 
-import grass.script         as grass
-import grass.script.setup   as gsetup
-from lmgr                   import datacatalog 
-from core.gcmd              import RunCommand, GError, GMessage
+import grass.script as grass
+import grass.script.setup as gsetup
+from lmgr import datacatalog
+from core.gcmd import RunCommand, GError, GMessage
 
+#===============================================================================
+# MAIN FRAME
+#===============================================================================
 
 
-#===============================================================================
-# MAIN        
-#===============================================================================
 class MdMainFrame(wx.Frame):
 
-    def __init__(self, jinjaPath=None, xmlPath=None, pos=None):
-        """Constructor"""
-        wx.Frame.__init__(self, None, title="Metadata Editor",
-                          size=(650, 500), pos=pos)
-        # self.template
-        
-        self.initDefaultPathOfStorageMetadata()
-        
-        
+    '''Main frame of metadata editor
+    '''
+
+    def __init__(self, jinjaPath=None, xmlPath=None, init=False):
+        '''
+        @param jinjaPath: path to jinja template
+        @param xmlPath: path to xml with will be read by editor
+        @var first,firstAfterChoice,second,secondAfterChoice,secondMultiEdit: initMultipleEditor() and onInitEditor() handler
+        @var self. initMultipleEditor() and onInitEditor() handler
+        @var self.templateEditor: true= Editor is in mode 'Template creator(widgets with chkbox)'
+        @var nameTMPtemplate: in case if 'template editor is on' this var holds name oof temporaly jinja template
+        @var batch: if true multiple editing metadata of maps is ON
+        '''
+        wx.Frame.__init__(self, None, title="Metadata Editor", size=(650, 500))
+        self.initDefaultPathStorageMetadata()
+
         self.jinjaPath = jinjaPath
         self.xmlPath = xmlPath
         self.first = True
         self.firstAfterChoice = False
         self.second = False
         self.secondAfterChoice = False
-        self.templateEditor=False
+        self.secondMultiEdit = False
+
+        self.templateEditor = False
         self.sb = self.CreateStatusBar()
-        self.secondMultiEdit=False
-        self.cres=0 #resizeFrame
-        self.nameTMPteplate=None
-        self.batch=False
+
+        self.cres = 0  # resizeFrame
+        self.nameTMPteplate = None
+        self.batch = False
+
         self.onInitEditor()
-        
-        
-        pub.subscribe(self.onCreateNewMD, 'NEW_MD.create')
+
+        pub.subscribe(self.initNewMD, 'NEW_MD.create')
         pub.subscribe(self.onEditingMode, 'EDITING_MODE.update')
-        pub.subscribe(self.onSetStatusbarText, 'STATUS_BAR_TEXT.update')
-        pub.subscribe(self.onExportTemplate,'EXPORT_TEMPLATE.create')
-        pub.subscribe(self.onExportXML,'EXPORT_XML.create')
-        pub.subscribe(self.onEditMapMetadata,'EDIT_MAP_METADATA.create')  
-        pub.subscribe(self.onInitEditor,'INIT_EDITOR.create') 
-        pub.subscribe(self.onTemplateEditor,'TEMPLATE_EDITOR_STATUS.update')      
-        pub.subscribe(self.onHideLeftPanel,'HIDE_LEFT_PANEL.update')            
-        pub.subscribe(self.onExportXMLforRefreshTreeBrowser,'REFRESH_TREE_BROWSER.update')   
-        pub.subscribe(self.onChangeEditMapProfile,'ISO_PROFILE.update') 
-        pub.subscribe(self.onUpdateGrassMetadata,'GRASS_METADATA.update')
-        pub.subscribe(self.onMdDestionation,'MD_DESTINATION.update')
-        pub.subscribe(self.onSetJaX,'SET_JINJA_AND_XML.update')
-        
-    def onSetJaX(self,jinja,xml):
-        self.jinjaPath=jinja
-        self.xmlPath=xml
-    def onMdDestionation(self,value):
-        self.mdDestination=value    
-            
-    def initDefaultPathOfStorageMetadata(self):    
-        self.mdDestination=os.path.join(mdutil.pathToMapset(),'metadata')    
+        pub.subscribe(self.setStatusbarText, 'STATUS_BAR_TEXT.update')
+        pub.subscribe(self.onExportTemplate, 'EXPORT_TEMPLATE.create')
+        pub.subscribe(self.onExportXML, 'EXPORT_XML.create')
+        pub.subscribe(self.onEditMapMetadata, 'EDIT_MAP_METADATA.create')
+        pub.subscribe(self.onInitEditor, 'INIT_EDITOR.create')
+        pub.subscribe(self.onTemplateEditor, 'TEMPLATE_EDITOR_STATUS.update')
+        pub.subscribe(self.onHideLeftPanel, 'HIDE_LEFT_PANEL.update')
+        pub.subscribe(self.onRefreshTreeBrowser, 'REFRESH_TREE_BROWSER.update')
+        pub.subscribe(self.onChangeEditMapProfile, 'ISO_PROFILE.update')
+        pub.subscribe(self.onUpdateGrassMetadata, 'GRASS_METADATA.update')
+        pub.subscribe(self.onSetJaX, 'MD_DESTINATION.update')
+        pub.subscribe(self.onSetJaX, 'SET_JINJA_AND_XML.update')
+
+    def onSetJaX(self, jinja, xml):
+        '''Set template ad xml paths
+        '''
+        self.jinjaPath = jinja
+        self.xmlPath = xml
+
+    def setMdDestionation(self, value):
+        '''Set md
+        '''
+        self.mdDestination = value
+
+    def initDefaultPathStorageMetadata(self):
+        '''set working folder
+        '''
+        self.mdDestination = os.path.join(mdutil.pathToMapset(), 'metadata')
         if not os.path.exists(self.mdDestination):
-                os.makedirs(self.mdDestination)
-                
+            os.makedirs(self.mdDestination)
+
     def onUpdateGrassMetadata(self):
-        md=self.editor.createNewMD()
+        '''Update r.support and v.support
+        '''
+        md = self.editor.createNewMD()
         self.mdCreator.updateGrassMd(md)
         GMessage('Grass metadata has been updated')
-        
+
     def onChangeEditMapProfile(self):
-        self.templateChoice=self.configPanelLeft.comboBoxProfile.GetValue()
-        self.ntbRight.profile=self.templateChoice
-        
-    def onExportTemplate(self,outPath,outFileName):
-        
-            self.editor.exportTemplate(self.jinjaPath,
-                                outPath=outPath,
-                                xmlOutName=outFileName)            
-   
-    def onExportXML(self,outPath,outFileName):
+        '''Update vars
+        '''
+        self.templateChoice = self.configPanelLeft.comboBoxProfile.GetValue()
+        self.ntbRight.profile = self.templateChoice
+
+    def onExportTemplate(self, outPath, outFileName):
+        '''Export defined(pre-filled) template
+        '''
+        self.editor.exportTemplate(self.jinjaPath,
+                                   outPath=outPath,
+                                   xmlOutName=outFileName)
+
+    def onExportXML(self, outPath, outFileName):
+        '''Save metadta xml file
+        '''
         if outPath is None and outFileName is None:
-            
             XMLhead, XMLtail = os.path.split(self.xmlPath)
             self.editor.exportToXml(self.jinjaPath,
-                                outPath=XMLhead,
-                                xmlOutName=XMLtail,
-                                msg=False)            
+                                    outPath=XMLhead,
+                                    xmlOutName=XMLtail,
+                                    msg=False)
         else:
             self.editor.exportToXml(self.jinjaPath,
-                                outPath=outPath,
-                                xmlOutName=outFileName,
-                                msg=True)
-        
-    def onExportXMLforRefreshTreeBrowser(self):   
-         path=os.path.dirname(os.path.realpath(__file__))
-         name='refreshTreeBrowser.xml'
-         self.editor.exportToXml(self.jinjaPath,
+                                    outPath=outPath,
+                                    xmlOutName=outFileName,
+                                    msg=True)
+
+    def onRefreshTreeBrowser(self):
+        '''Update changes from editor in tree browser
+        '''
+        path = os.path.dirname(os.path.realpath(__file__))
+        name = 'refreshTreeBrowser.xml'
+        self.editor.exportToXml(self.jinjaPath,
                                 outPath=path,
                                 xmlOutName=name,
                                 msg=False)
-         
-         pathName=os.path.join(path,name)
-         self.ntbRight.refreshXmlBrowser(pathName)
-         os.remove(pathName)
 
-    def onSetStatusbarText(self,text):
+        pathName = os.path.join(path, name)
+        self.ntbRight.refreshXmlBrowser(pathName)
+        os.remove(pathName)
+
+    def setStatusbarText(self, text):
+        '''Set status text
+        '''
         self.sb.SetStatusText(text)
-    
-    def onTemplateEditor(self,value,template=None):
-        self.templateEditor=value
-        if  template== None:
-            self.nameTMPteplate='TMPtemplate' 
-        if template ==False:
-            self.nameTMPteplate=None
-         
-    def onCreateNewMD(self):
+
+    def onTemplateEditor(self, value, template=None):
+        '''Update local var
+        '''
+        self.templateEditor = value
+        if template == None:
+            self.nameTMPteplate = 'TMPtemplate'
+        if template == False:
+            self.nameTMPteplate = None
+
+    def initNewMD(self):
+        '''Init new md OWSLib  object
+        '''
         self.editor.createNewMD()
-        self.ntbRight.md=self.editor.md
-        
+        self.ntbRight.md = self.editor.md
+
     def resizeFrame(self, x1=1, y1=0):
-        self.cres+=1
-        if (self.cres%2==0) and x1==1 and y1==0:
-            x1=-1
+        '''Some widgets need refresh frame for proper working
+        '''
+        self.cres += 1
+        if (self.cres % 2 == 0) and x1 == 1 and y1 == 0:
+            x1 = -1
         x, y = self.GetSize()
-        self.SetSize((x + x1, y + y1)) 
-                 
+        self.SetSize((x + x1, y + y1))
+
     def onHideLeftPanel(self):
+        '''in editing mode is config panel hidden
+        '''
         self.toolbar.bttNew.Enable()
         self.Hsizer.Remove(self.leftPanel)
         self.Hsizer.Layout()
         self.leftPanel.SetSize((1, 1))
-        #self.splitter.Refresh()
-        #self.splitter.SetSashGravity(0.7)        
-                         
-    def onEditMapMetadata(self,multipleEditing=False):
-        if not multipleEditing:
-            self.ListOfMapTypeDict=self.MdDataCatalogPanelLeft.ListOfMapTypeDict
-            
-        self.templateChoice=self.configPanelLeft.comboBoxProfile.GetValue()    
-        self.numOfMap=len(self.ListOfMapTypeDict)
-                
-        if self.numOfMap==0 and  multipleEditing is False:          
-             GMessage('Select map in data catalog...') 
-             return
-         
-        #if editing just one map  
-        if  self.numOfMap==1 and multipleEditing is False:
-                self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][ self.ListOfMapTypeDict[-1].keys()[0] ],
-                                                 self.ListOfMapTypeDict[-1].keys()[0])                
-                if self.templateChoice == 'INSPIRE':
-                    self.mdCreator.createGrassInspireISO()
-                    self.jinjaPath = self.mdCreator.templatePathAbs
-                    self.xmlPath = self.mdCreator.saveXML(self.mdDestination,self.nameTMPteplate,self)
-                    self.onInitEditor()
-                    
-                elif self.templateChoice == 'GRASS BASIC':
-                    self.mdCreator.createGrassBasicISO()
-                    self.jinjaPath = self.mdCreator.templatePathAbs
-                    self.xmlPath = self.mdCreator.saveXML(self.mdDestination,self.nameTMPteplate,self)
-                    self.onInitEditor()
-                    
-        #if editing multiple maps or just one but with loading own custom template
-        if self.templateChoice == 'Load Custom' and self.numOfMap!=0:   
-            #load template. IF for just one map ELSE for multiple editing
-            if multipleEditing is False:
-                dlg = wx.FileDialog(self,"Choose a template", os.getcwd(),"","*.xml",wx.OPEN)
-                if dlg.ShowModal() == wx.ID_OK:
-                        self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][ self.ListOfMapTypeDict[-1].keys()[0] ],
-                                                     self.ListOfMapTypeDict[-1].keys()[0])    
-                        self.mdCreator.createGrassInspireISO()
-                        self.jinjaPath = dlg.GetPath()
-                        self.xmlPath = self.mdCreator.saveXML(self.mdDestination,self.nameTMPteplate,self)
-                        #if multiple map are selected
-                        if self.numOfMap>1:
-                            self.toolbar.xmlPath=self.xmlPath
-                            self.toolbar.jinjaPath=self.jinjaPath
-                            self.batch=True
-                            self.ListOfMapTypeDict.pop()
-                            self.initMultipleEditor()
-                            
-                        else:
-                            self.ListOfMapTypeDict.pop()
-                            self.onInitEditor() 
-                else:#do nothing
-                    return False#not continue
-            else:#
-                        self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][ self.ListOfMapTypeDict[-1].keys()[0] ],
-                                                     self.ListOfMapTypeDict[-1].keys()[0])    
-                        self.mdCreator.createGrassInspireISO()                
-                        self.xmlPath = self.mdCreator.saveXML(self.mdDestination,self.nameTMPteplate,self)
-                        self.toolbar.xmlPath=self.xmlPath
-                        self.toolbar.jinjaPath=self.jinjaPath
-                        self.ListOfMapTypeDict
-                        self.initMultipleEditor()
-                        self.ListOfMapTypeDict.pop()
-        if not multipleEditing:
-            self.onHideLeftPanel()                        
-        if self.numOfMap==0 and  multipleEditing is True:
-            multipleEditing=False
-            self.toolbar.onNewSession(None)
-            GMessage('All selected maps are edited') 
-            self.secondMultiEdit=True
-            #self.batch=False
-              
 
-                            
-        #=======================================================================
-        # if self.numOfMap>1 and  self.templateChoice != 'Load Custom':
-        #      GMessage('For multiple editing metadata of maps is necessary to define template and use "Load Custom" option. See manual... ')
-        #      self.toolbar.onNewSession(None)
-        #======================================================================= 
-        if self.batch and multipleEditing :
-            XMLhead, XMLtail = os.path.split(self.xmlPath)
-            self.batch=mdutil.yesNo(self, 'Do you want to save metadata of : %s without editing ? '%XMLtail)
-            
-            if self.batch:
-                self.toolbar.batch=True
-                self.toolbar.onSaveXML()
-        return True
-       
     def onEditingMode(self, editStatus):
         self.resizeFrame()
         self.Layout()
-        
+
         if editStatus:
             self.MdDataCatalogPanelLeft.Show()
             self.toolbar.bttLoad.Disable()
             self.toolbar.bttLoadXml.Disable()
-            #self.toolbar.bttEdit.Enable()
         else:
             self.MdDataCatalogPanelLeft.Hide()
             self.toolbar.bttEdit.Disable()
@@ -261,249 +214,338 @@
             self.toolbar.bttLoadXml.Enable()
             self.sb.SetStatusText('')
             self.MdDataCatalogPanelLeft.UnselectAll()
-    
-    def initMultipleEditor(self):
-            if self.firstAfterChoice and not self.secondMultiEdit:
-                    self.splitter = SplitterWindow(self, style=wx.SP_3D |
-                                                wx.SP_LIVE_UPDATE|wx.SP_BORDER)      
-                    self.Hsizer.Add(self.splitter, proportion=1, flag=wx.EXPAND)
-             
-                    self.firstAfterChoice = False
-                    self.secondAfterChoice = True
-                    self.toolbar.bttsave.SetLabel('next')
-                    self.toolbar.hideMultipleEdit()
-                    self.mainSizer.Layout()
-                    self.editor = MdMainEditor(
-                                            self.splitter,
-                                            self.jinjaPath,
-                                            self.xmlPath,
-                                            self.templateEditor)
-                    self.ntbRight = NotebookRight(self.splitter, self.xmlPath)
-                    self.splitter.SplitVertically(self.editor, self.ntbRight, sashPosition=0.65)
-                    self.splitter.SetSashGravity(0.65)   
-                    self.resizeFrame()
-                    self.Show()
-                    
-            elif self.secondAfterChoice or self.secondMultiEdit:
-                    if self.secondMultiEdit:
-                        self.toolbar.bttsave.SetLabel('next')
-                        self.toolbar.hideMultipleEdit()
-                    self.second=False
-                    self.secondAfterChoice=True
-                    
-                    self.onInitEditor() 
+
+    def onEditMapMetadata(self, multipleEditing=False):
+        '''Initialize editor by selection of grass map in data catalog
+        @param multipleEditing: if user select more than one map mutlipleEditing=True
+        @param numOfMap: hold information about number of selected maps for editing
+        @param ListOfMapTypeDict: list of dict sttored names of selected maps in dict. dict['cell/vector']=nameofmaps
+        '''
+        if not multipleEditing:
+            self.ListOfMapTypeDict = self.MdDataCatalogPanelLeft.ListOfMapTypeDict
+
+        self.templateChoice = self.configPanelLeft.comboBoxProfile.GetValue()
+        self.numOfMap = len(self.ListOfMapTypeDict)
+
+        if self.numOfMap == 0 and multipleEditing is False:
+            GMessage('Select map in data catalog...')
             return
 
+        # if editing just one map
+        if self.numOfMap == 1 and multipleEditing is False:
+            self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][self.ListOfMapTypeDict[-1].keys()[0]],
+                                             self.ListOfMapTypeDict[-1].keys()[0])
+            if self.templateChoice == 'INSPIRE':
+                self.mdCreator.createGrassInspireISO()
+                self.jinjaPath = self.mdCreator.templatePathAbs
+                self.xmlPath = self.mdCreator.saveXML(self.mdDestination, self.nameTMPteplate, self)
+                self.onInitEditor()
+
+            elif self.templateChoice == 'GRASS BASIC':
+                self.mdCreator.createGrassBasicISO()
+                self.jinjaPath = self.mdCreator.templatePathAbs
+                self.xmlPath = self.mdCreator.saveXML(self.mdDestination, self.nameTMPteplate, self)
+                self.onInitEditor()
+
+        # if editing multiple maps or just one but with loading own custom template
+        if self.templateChoice == 'Load Custom' and self.numOfMap != 0:
+        # load template. IF for just one map ELSE for multiple editing
+            if multipleEditing is False:
+                dlg = wx.FileDialog(self, "Select template", os.getcwd(), "", "*.xml", wx.OPEN)
+                if dlg.ShowModal() == wx.ID_OK:
+                    self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][self.ListOfMapTypeDict[-1].keys()[0]],
+                                                     self.ListOfMapTypeDict[-1].keys()[0])
+                    self.mdCreator.createGrassInspireISO()
+                    self.jinjaPath = dlg.GetPath()
+                    self.xmlPath = self.mdCreator.saveXML(self.mdDestination, self.nameTMPteplate, self)
+                    # if multiple map are selected
+                    if self.numOfMap > 1:
+                        self.toolbar.xmlPath = self.xmlPath
+                        self.toolbar.jinjaPath = self.jinjaPath
+                        self.batch = True
+                        self.ListOfMapTypeDict.pop()
+                        self.initMultipleEditor()
+                    else:
+                        self.ListOfMapTypeDict.pop()
+                        self.onInitEditor()
+                else:  # do nothing
+                    return False
+            else:
+                self.mdCreator = mdgrass.GrassMD(self.ListOfMapTypeDict[-1][self.ListOfMapTypeDict[-1].keys()[0]],
+                                                 self.ListOfMapTypeDict[-1].keys()[0])
+                self.mdCreator.createGrassInspireISO()
+                self.xmlPath = self.mdCreator.saveXML(self.mdDestination, self.nameTMPteplate, self)
+                self.toolbar.xmlPath = self.xmlPath
+                self.toolbar.jinjaPath = self.jinjaPath
+                self.ListOfMapTypeDict
+                self.initMultipleEditor()
+                self.ListOfMapTypeDict.pop()
+
+        if not multipleEditing:
+            self.onHideLeftPanel()
+
+        if self.numOfMap == 0 and multipleEditing is True:
+            multipleEditing = False
+            self.toolbar.onNewSession(None)
+            GMessage('All selected maps are edited')
+            self.secondMultiEdit = True
+
+        if self.batch and multipleEditing:
+            XMLhead, XMLtail = os.path.split(self.xmlPath)
+            self.batch = mdutil.yesNo(self, 'Do you want to save metadata of : %s without editing ? ' % XMLtail, 'Multiple editing')
+
+            if self.batch:
+                self.toolbar.batch = True
+                self.toolbar.onSaveXML()
+        return True
+
+    def initMultipleEditor(self):
+        '''initialize multiple editing mode
+        '''
+        if self.firstAfterChoice and not self.secondMultiEdit:
+            self.splitter = SplitterWindow(self, style=wx.SP_3D |
+                                           wx.SP_LIVE_UPDATE | wx.SP_BORDER)
+            self.Hsizer.Add(self.splitter, proportion=1, flag=wx.EXPAND)
+
+            self.firstAfterChoice = False
+            self.secondAfterChoice = True
+            self.toolbar.bttsave.SetLabel('next')
+            self.toolbar.hideMultipleEdit()
+            self.mainSizer.Layout()
+            self.editor = MdMainEditor(self.splitter,
+                                       self.jinjaPath,
+                                       self.xmlPath,
+                                       self.templateEditor)
+            self.ntbRight = NotebookRight(self.splitter, self.xmlPath)
+            self.splitter.SplitVertically(self.editor, self.ntbRight, sashPosition=0.65)
+            self.splitter.SetSashGravity(0.65)
+            self.resizeFrame()
+            self.Show()
+
+        elif self.secondAfterChoice or self.secondMultiEdit:
+            if self.secondMultiEdit:
+                self.toolbar.bttsave.SetLabel('next')
+                self.toolbar.hideMultipleEdit()
+            self.second = False
+            self.secondAfterChoice = True
+            self.onInitEditor()
+
     def onInitEditor(self,):
-                              
-            if self.first:
-                self.first = False
-                self.firstAfterChoice = True
-                self.toolbar = MdToolbar(self,self.jinjaPath,
-                                         self.xmlPath,
-                                         self.sb,
-                                         self.mdDestination)
+        '''Initialize editor
+        @var first: True= First initialize main frame
+        @var firstAfterChoice: True=Init editor editor after set configuration and click onEdit in toolbar
+        @var second: init editor after first initialize
+        @var secondAfterChoice: init edito onemore time
+        '''
+        if self.first:
+            self.first = False
+            self.firstAfterChoice = True
+            self.toolbar = MdToolbar(self,
+                                     self.jinjaPath,
+                                     self.xmlPath,
+                                     self.sb,
+                                     self.mdDestination)
 
-                self.leftPanel = wx.Panel(self, id=wx.ID_ANY)
-                self.configPanelLeft = MdEditConfigPanel(self.leftPanel)
-                self.MdDataCatalogPanelLeft = MdDataCatalog(self.leftPanel)
-                              
-                
-                self._layout()
-                self.Show()
-                
-            elif self.firstAfterChoice:
-                    self.splitter = SplitterWindow(self, style=wx.SP_3D |
-                                                wx.SP_LIVE_UPDATE|wx.SP_BORDER)
-                    
-                    self.secondMultiEdit=True
-                    self.firstAfterChoice = False
-                    self.second = True
+            self.leftPanel = wx.Panel(self, id=wx.ID_ANY)
+            self.configPanelLeft = MdEditConfigPanel(self.leftPanel)
+            self.MdDataCatalogPanelLeft = MdDataCatalog(self.leftPanel)
 
-                    self.editor = MdMainEditor(
-                                            parent=self.splitter,
-                                            templatePath=self.jinjaPath,
-                                            mdISOXML=self.xmlPath,
-                                            templateEditor=self.templateEditor)
-                    
-                    self.ntbRight = NotebookRight(self.splitter, self.xmlPath)
-                    
-                    self.splitter.SplitVertically(self.editor, self.ntbRight, sashPosition=0.65)
-                    self.splitter.SetSashGravity(0.65) 
-                    self.Hsizer.Add(self.splitter, proportion=1, flag=wx.EXPAND)
-                    self.splitter.SizeWindows()
-                    self.resizeFrame()
-                    self.Show()
-            
-            elif self.second:  # if next initializing of editor
-                self.second = False
-                self.secondAfterChoice = True
-                self.splitter.Hide()
-                self.toolbar.bttNew.Disable()
-                self.toolbar.bttsave.Disable()
-                
-                self.Hsizer.Insert(0, self.leftPanel, proportion=1, flag=wx.EXPAND)
-                self.resizeFrame()
-                
-            elif self.secondAfterChoice:
-                    self.secondAfterChoice = False
-                    self.second = True
-                    self.splitter.Show()
-                    self.toolbar.bttNew.Enable() 
-                    self.toolbar.bttsave.Enable()
-                    
-                    ntbRightBCK = self.ntbRight     
-                    self.ntbRight = NotebookRight(self.splitter, self.xmlPath) 
-                    self.splitter.ReplaceWindow(ntbRightBCK, self.ntbRight)                 
-                    
-                    editorTMP = self.editor
-                    self.editor = MdMainEditor(
-                                            parent=self.splitter,
-                                            templatePath=self.jinjaPath,
-                                            mdISOXML=self.xmlPath,
-                                            templateEditor=self.templateEditor)
-                    
-                    self.splitter.ReplaceWindow(editorTMP, self.editor)
-                    ntbRightBCK.Destroy()
-                    editorTMP.Destroy()
-                    self.resizeFrame()
-                    self.Show()
-                    self.splitter.SetSashGravity(0.35)                
-            else:
-                GMessage('Select map in data catalog...')
-            
-            self.toolbar.xmlPath=self.xmlPath
-            self.toolbar.jinjaPath=self.jinjaPath
-            
+            self._layout()
+            self.Show()
+
+        elif self.firstAfterChoice:
+            self.splitter = SplitterWindow(self, style=wx.SP_3D | wx.SP_LIVE_UPDATE | wx.SP_BORDER)
+            self.secondMultiEdit = True
+            self.firstAfterChoice = False
+            self.second = True
+
+            self.editor = MdMainEditor(parent=self.splitter,
+                                       templatePath=self.jinjaPath,
+                                       xmlMdPath=self.xmlPath,
+                                       templateEditor=self.templateEditor)
+
+            self.ntbRight = NotebookRight(self.splitter, self.xmlPath)
+
+            self.splitter.SplitVertically(self.editor, self.ntbRight, sashPosition=0.65)
+            self.splitter.SetSashGravity(0.65)
+            self.Hsizer.Add(self.splitter, proportion=1, flag=wx.EXPAND)
+            self.splitter.SizeWindows()
+            self.resizeFrame()
+            self.Show()
+
+        elif self.second:  # if next initializing of editor
+            self.second = False
+            self.secondAfterChoice = True
+            self.splitter.Hide()
+            self.toolbar.bttNew.Disable()
+            self.toolbar.bttsave.Disable()
+
+            self.Hsizer.Insert(0, self.leftPanel, proportion=1, flag=wx.EXPAND)
+            self.resizeFrame()
+
+        elif self.secondAfterChoice:
+            self.secondAfterChoice = False
+            self.second = True
+            self.splitter.Show()
+            self.toolbar.bttNew.Enable()
+            self.toolbar.bttsave.Enable()
+
+            ntbRightBCK = self.ntbRight
+            self.ntbRight = NotebookRight(self.splitter, self.xmlPath)
+            self.splitter.ReplaceWindow(ntbRightBCK, self.ntbRight)
+
+            editorTMP = self.editor
+            self.editor = MdMainEditor(parent=self.splitter,
+                                       templatePath=self.jinjaPath,
+                                       xmlMdPath=self.xmlPath,
+                                       templateEditor=self.templateEditor)
+
+            self.splitter.ReplaceWindow(editorTMP, self.editor)
+            ntbRightBCK.Destroy()
+            editorTMP.Destroy()
+            self.resizeFrame()
+            self.Show()
+            self.splitter.SetSashGravity(0.35)
+        else:
+            GMessage('Select map in data catalog...')
+
+            self.toolbar.xmlPath = self.xmlPath
+            self.toolbar.jinjaPath = self.jinjaPath
+
     def _layout(self):
-        
-            self.mainSizer = wx.BoxSizer(wx.VERTICAL)
-            self.SetSizer(self.mainSizer)
-                
-            self.mainSizer.Add(self.toolbar)
-            self.mainSizer.Add(
-                wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL, size=(10000, 5)))
-            self.mainSizer.AddSpacer(5, 5, 1, wx.EXPAND)
-    
-            self.leftPanelSizer = wx.BoxSizer(wx.VERTICAL)
-            self.leftPanel.SetSizer(self.leftPanelSizer)
-            self.leftPanelSizer.Add(self.configPanelLeft, proportion=0, flag=wx.EXPAND)
-            self.leftPanelSizer.AddSpacer(5, 5, 1, wx.EXPAND)
-            self.leftPanelSizer.Add(self.MdDataCatalogPanelLeft, proportion=1, flag=wx.EXPAND)
-        
-            self.Hsizer = wx.BoxSizer(wx.HORIZONTAL)
-            self.mainSizer.Add(self.Hsizer, proportion=1, flag=wx.EXPAND)        
-        
-            self.Hsizer.Add(self.leftPanel, proportion=1, flag=wx.EXPAND)
-            
-            
 
-            self.resizeFrame(300, 0)
-            self.Layout()
+        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.mainSizer)
+
+        self.mainSizer.Add(self.toolbar)
+        self.mainSizer.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL, size=(10000, 5)))
+        self.mainSizer.AddSpacer(5, 5, 1, wx.EXPAND)
+
+        self.leftPanelSizer = wx.BoxSizer(wx.VERTICAL)
+        self.leftPanel.SetSizer(self.leftPanelSizer)
+        self.leftPanelSizer.Add(self.configPanelLeft, proportion=0, flag=wx.EXPAND)
+        self.leftPanelSizer.AddSpacer(5, 5, 1, wx.EXPAND)
+        self.leftPanelSizer.Add(self.MdDataCatalogPanelLeft, proportion=1, flag=wx.EXPAND)
+
+        self.Hsizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.mainSizer.Add(self.Hsizer, proportion=1, flag=wx.EXPAND)
+
+        self.Hsizer.Add(self.leftPanel, proportion=1, flag=wx.EXPAND)
+
+        self.resizeFrame(300, 0)
+        self.Layout()
 #===============================================================================
 # DATA CATALOG
 #===============================================================================
+
+
 class MdDataCatalog(datacatalog.LocationMapTree):
-    
-        def __init__(self, parent):
-            """Test Tree constructor."""
-            super(MdDataCatalog, self).__init__(parent=parent,style=wx.TR_MULTIPLE|wx.TR_HIDE_ROOT |
-                                                 wx.TR_HAS_BUTTONS|wx.TR_FULL_ROW_HIGHLIGHT|
-                                                 wx.TR_COLUMN_LINES )
 
-            self.InitTreeItems()
-            self.map = None
-            self.mapType = None
-            
-        def InitTreeItems(self):
-            """Add locations, mapsets and layers to the tree."""
-            gisenv = grass.gisenv()
-            location = gisenv['LOCATION_NAME']
-            self.mapset = gisenv['MAPSET']
-            self._initTreeItems(locations=[location],
-                                mapsets=[self.mapset])
-            self.ExpandAll()
-            self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChanged)
-            self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onChanged)
-            
-        def onChanged(self, evt=None): 
-            self.ListOfMapTypeDict=list()
-            maps=list()
-            if self.GetChildrenCount(evt.Item) == 0:
-                for item in self.GetSelections():
-                    MapTypeDict={}
-                    maps.append(self.GetItemText(item))
-                    map = self.GetItemText(item) + '@' + self.mapset
-                    mapType = self.GetItemParent(item)
-                    mapType = self.GetItemText(mapType) 
-                                  
-                    if mapType == 'vect':
-                        mapType = 'vector'
-                    elif mapType == 'rast':
-                        mapType = 'cell'
-                    MapTypeDict[mapType]  = map
-                    
-                    self.ListOfMapTypeDict.append(MapTypeDict)  
-                pub.sendMessage('bttEdit.enable')
-                pub.sendMessage('bttCreateTemplate.enable')
-                
-            else:
-                self.Unselect()
-                GMessage('Please select map.')
-              
-            if len(maps)==0:
-                pub.sendMessage('bttEdit.disable')
-                pub.sendMessage('bttCreateTemplate.disable') 
-            str1=''
-            
-            for map in maps:
-                str1+=map+'  '
-            
-            if len(maps)>1:
-                pub.sendMessage('SET_PROFILE.update',profile='Load Custom')
+    '''Data catalog for selecting GRASS maps for editing
+    '''
 
-                pub.sendMessage('comboBoxProfile.disable')
-                pub.sendMessage('bttCreateTemplate.disable')
-            else:
-                pub.sendMessage('comboBoxProfile.enable')
-                pub.sendMessage('bttCreateTemplate.enable')
-                
-            pub.sendMessage('STATUS_BAR_TEXT.update',text=str1)    
-            
+    def __init__(self, parent):
+        """Test Tree constructor."""
+        super(MdDataCatalog, self).__init__(parent=parent,
+                                            style=wx.TR_MULTIPLE | wx.TR_HIDE_ROOT | wx.TR_HAS_BUTTONS |
+                                            wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES)
+        self.InitTreeItems()
+        self.map = None
+        self.mapType = None
 
+    def InitTreeItems(self):
+        """Add locations and layers to the tree."""
+        gisenv = grass.gisenv()
+        location = gisenv['LOCATION_NAME']
+        self.mapset = gisenv['MAPSET']
+
+        self._initTreeItems(locations=[location], mapsets=[self.mapset])
+        self.ExpandAll()
+        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChanged)
+        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onChanged)
+
+    def onChanged(self, evt=None):
+        '''
+        @var ListOfMapTypeDict: list of dic with maps and map-type values
+        @var MapTypeDict: keys= type of map(cell/vector), value=<map name>
+        '''
+        self.ListOfMapTypeDict = list()
+        maps = list()
+        if self.GetChildrenCount(evt.Item) == 0:  # is selected map
+            for item in self.GetSelections():
+                MapTypeDict = {}
+                maps.append(self.GetItemText(item))
+                map = self.GetItemText(item) + '@' + self.mapset
+                mapType = self.GetItemParent(item)
+                mapType = self.GetItemText(mapType)
+
+                if mapType == 'vect':
+                    mapType = 'vector'
+                elif mapType == 'rast':
+                    mapType = 'cell'
+                MapTypeDict[mapType] = map
+
+                self.ListOfMapTypeDict.append(MapTypeDict)
+            pub.sendMessage('bttEdit.enable')
+            pub.sendMessage('bttCreateTemplate.enable')
+
+        else:
+            self.Unselect()
+            GMessage('Please select map.')
+
+        if len(maps) == 0:
+            pub.sendMessage('bttEdit.disable')
+            pub.sendMessage('bttCreateTemplate.disable')
+        str1 = ''
+
+        for map in maps:
+            str1 += map + '  '
+
+        if len(maps) > 1:
+            pub.sendMessage('SET_PROFILE.update', profile='Load Custom')
+
+            pub.sendMessage('comboBoxProfile.disable')
+            pub.sendMessage('bttCreateTemplate.disable')
+        else:
+            pub.sendMessage('comboBoxProfile.enable')
+            pub.sendMessage('bttCreateTemplate.enable')
+
+        pub.sendMessage('STATUS_BAR_TEXT.update', text=str1)
+
 #===============================================================================
 # NOTEBOOK ON THE RIGHT SIDE-xml browser+validator
 #===============================================================================
+
+
 class NotebookRight(wx.Notebook):
 
+    '''Include pages with xml tree browser and validator of metadata
+    '''
+
     def __init__(self, parent, path):
+
         wx.Notebook.__init__(self, parent=parent, id=wx.ID_ANY)
         # first panel
         self.notebookValidator = wx.Panel(self, wx.ID_ANY)
         self.validator = MdValidator(self.notebookValidator)
-        self.xmlPath=path
-        self.profile=None
-        self.buttValidate = wx.Button(
-                                    self.notebookValidator,
-                                    id=wx.ID_ANY,
-                                    size=(
-                                        70,
-                                        50),
-                                    label='validate')
+        self.xmlPath = path
+        self.profile = None
+        self.buttValidate = wx.Button(self.notebookValidator,
+                                      id=wx.ID_ANY,
+                                      size=(70, 50),
+                                      label='validate')
 
         self.notebook_panel1 = wx.Panel(self, wx.ID_ANY)
-        self.tree = TreeEditor(self.notebook_panel1, self.xmlPath)
+        self.tree = TreeBrowser(self.notebook_panel1, self.xmlPath)
         self.buttRefresh = wx.Button(
-                                    self.notebook_panel1,
-                                    id=wx.ID_ANY,
-                                    size=(
-                                        70,
-                                        50),
-                                    label='refresh') 
+            self.notebook_panel1,
+            id=wx.ID_ANY,
+            size=(70, 50),
+            label='refresh')
 
         self.AddPage(self.notebookValidator, "Validator")
         self.AddPage(self.notebook_panel1, "Tree browser")
-        #self.AddPage(self.notebook_panel2, "Help")
+        # self.AddPage(self.notebook_panel2, "Help")
 
         self.buttValidate.Bind(wx.EVT_BUTTON, self.validate)
         self.buttRefresh.Bind(wx.EVT_BUTTON, self.onRefreshXmlBrowser)
@@ -511,24 +553,23 @@
 
     def onActive(self):
         pass
-    
-    def onRefreshXmlBrowser(self,evt=None):
-        pub.sendMessage( 'REFRESH_TREE_BROWSER.update')
 
-    def refreshXmlBrowser(self,path):
-        treeBCK=self.tree
-        self.tree=TreeEditor(self.notebook_panel1,path)
+    def onRefreshXmlBrowser(self, evt=None):
+        pub.sendMessage('REFRESH_TREE_BROWSER.update')
+
+    def refreshXmlBrowser(self, path):
+        treeBCK = self.tree
+        self.tree = TreeBrowser(self.notebook_panel1, path)
         self.panelSizer1.Replace(treeBCK, self.tree)
-        #self.panelSizer1.Add(self.tree, flag=wx.EXPAND, proportion=1)
+        # self.panelSizer1.Add(self.tree, flag=wx.EXPAND, proportion=1)
         self.panelSizer1.Layout()
         treeBCK.Destroy()
-        
+
     def validate(self, evt):
-        self.md=None
-        
+        self.md = None
         pub.sendMessage('NEW_MD.create')
-        pub.sendMessage('ISO_PROFILE.update') 
-        self.validator.validate(self.md,self.profile)
+        pub.sendMessage('ISO_PROFILE.update')
+        self.validator.validate(self.md, self.profile)
 
     def _layout(self):
         panelSizer0 = wx.BoxSizer(wx.VERTICAL)
@@ -541,46 +582,55 @@
         self.notebook_panel1.SetSizer(self.panelSizer1)
         self.panelSizer1.Add(self.tree, flag=wx.EXPAND, proportion=1)
         self.panelSizer1.Add(self.buttRefresh)
-        
+
         panelSizer2 = wx.BoxSizer(wx.VERTICAL)
-        #self.notebook_panel2.SetSizer(panelSizer2)
-        #panelSizer2.Add(self.notebook_panel2,flag=wx.EXPAND, proportion=1)
+        # self.notebook_panel2.SetSizer(panelSizer2)
+        # panelSizer2.Add(self.notebook_panel2,flag=wx.EXPAND, proportion=1)
 #===============================================================================
-# HELP       
+# HELP
 #===============================================================================
+
+
 class MDHelp(wx.Panel):
+
     """
     class MyHtmlPanel inherits wx.Panel and adds a button and HtmlWindow
     """
-    def __init__(self, parent ):
+
+    def __init__(self, parent):
         wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
         self.html1 = wx.html.HtmlWindow(self, id=wx.ID_ANY)
         try:
             self.html1.LoadFile('help/help.html')
-            #self.html1.LoadPage('http://inspire-geoportal.ec.europa.eu/EUOSME_GEOPORTAL/userguide/eurlex_en.htm')
+            # self.html1.LoadPage('http://inspire-geoportal.ec.europa.eu/EUOSME_GEOPORTAL/userguide/eurlex_en.htm')
         except:
             pass
-        
+
         self.mainSizer = wx.BoxSizer(wx.VERTICAL)
         self.SetSizer(self.mainSizer)
-        self.mainSizer.Add(self.html1,proportion=1, flag=wx.EXPAND) 
-        
+        self.mainSizer.Add(self.html1, proportion=1, flag=wx.EXPAND)
 #===============================================================================
 # TREE EDITOR
 #===============================================================================
-class TreeEditor(wx.TreeCtrl):
 
-    def __init__(self, parent, xmlPath=False,xmlEtree=False):
-        wx.TreeCtrl.__init__(self,parent=parent,id=wx.ID_ANY,
-                             style=wx.TR_HAS_BUTTONS|wx.TR_FULL_ROW_HIGHLIGHT)
-        tree=self
+
+class TreeBrowser(wx.TreeCtrl):
+
+    '''Filling text tree by xml file.
+    @note: to enable editing mode of init xml uncoment blocks below
+    '''
+
+    def __init__(self, parent, xmlPath=False, xmlEtree=False):
+        wx.TreeCtrl.__init__(self, parent=parent, id=wx.ID_ANY,
+                             style=wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT)
+        tree = self
         if xmlPath:
             xml = etree.parse(xmlPath)
-            self.xml=xml.getroot()
-            
-            self.root = tree.AddRoot( self.xml.tag)
+            self.xml = xml.getroot()
+
+            self.root = tree.AddRoot(self.xml.tag)
         else:
-            self.xml=xmlEtree
+            self.xml = xmlEtree
             self.root = xmlEtree.getroot()
 
         root = self.fillTree()
@@ -593,17 +643,18 @@
         self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRClickAllChildren)
 
     def fillTree(self):
-        root=self.root 
-        xml=self.xml
-        tree=self
+        root = self.root
+        xml = self.xml
+        tree = self
+
         def add(parent, elem):
             for e in elem:
                 if str(e).find("<!--") != -1:  # skip comments
                     continue
                 tag = etree.QName(e)
                 item = tree.AppendItem(parent, tag.localname, data=None)
-                if self.GetChildrenCount(item) == 0:    
-                    self.SetItemBackgroundColour(item,(242,242,242))
+                if self.GetChildrenCount(item) == 0:
+                    self.SetItemBackgroundColour(item, (242, 242, 242))
                 if e.text:
                     text = e.text.strip()
                 else:
@@ -613,7 +664,7 @@
                     tree.SetPyData(val, e)
 
                 add(item, e)
-                
+
         add(root, xml)
         return root
 
@@ -621,7 +672,7 @@
     # def OnEdit(self, evt):
     #     elm = self.GetPyData(evt.Item)
     #
-    #     #print evt.Label
+    # print evt.Label
     #     if elm is not None:
     #         elm.text = evt.Label
     #         self.xml.write(self.fpath, encoding="UTF-8", xml_declaration=True)
@@ -638,17 +689,22 @@
             self.ExpandAllChildren(evt.Item)
         else:
             self.CollapseAllChildren(evt.Item)
-            
+
 #===============================================================================
-# INSPIRE VALIDATOR PANEL            
+# INSPIRE VALIDATOR PANEL
 #===============================================================================
+
+
 class MdValidator(wx.Panel):
 
+    '''wx panel of notebook which support validating two natively implemented profiles
+    '''
+
     def __init__(self, parent):
         wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
         self.text = wx.TextCtrl(parent, id=wx.ID_ANY, size=(0, 55),
-                                style=wx.VSCROLL | 
-                                wx.TE_MULTILINE | wx.TE_NO_VSCROLL | 
+                                style=wx.VSCROLL |
+                                wx.TE_MULTILINE | wx.TE_NO_VSCROLL |
                                 wx.TAB_TRAVERSAL | wx.RAISED_BORDER | wx.HSCROLL)
         self._layout()
 
@@ -656,42 +712,47 @@
         self.mainSizer = wx.BoxSizer(wx.VERTICAL)
         self.SetSizer(self.mainSizer)
         self.mainSizer.Add(self.text, proportion=1, flag=wx.EXPAND)
-        
-    def validate(self, md,profile):
-            if profile=='INSPIRE' or profile=='Load Custom':
-                result=mdutil.isnpireValidator(md)
-                str1 = 'INSPIRE VALIDATOR\n'
-                
-            if profile == 'GRASS BASIC':
-                result=mdutil.grassProfileValidator(md)
-                str1 = 'GRASS BASIC PROFILE VALIDATOR\n'     
-                     
-            str1 += 'Status of validation: ' + result["status"] + '\n'
-            str1 += 'Numbers of errors: ' + result["num_of_errors"] + '\n'
 
-            if result["status"] != 'succeded':
-                str1 += 'Errors:\n'
-                for item in result["errors"]:
-                    str1 += '\t' + str(item) + '\n'
-        
-            self.text.SetValue(str1)
+    def validate(self, md, profile):
+        '''For externaly load xml file is by default inspire validator
+        '''
+        if profile == 'INSPIRE' or profile == 'Load Custom':
+            result = mdutil.isnpireValidator(md)
+            str1 = 'INSPIRE VALIDATOR\n'
 
+        if profile == 'GRASS BASIC':
+            result = mdutil.grassProfileValidator(md)
+            str1 = 'GRASS BASIC PROFILE VALIDATOR\n'
 
-        
+        str1 += 'Status of validation: ' + result["status"] + '\n'
+        str1 += 'Numbers of errors: ' + result["num_of_errors"] + '\n'
+
+        if result["status"] != 'succeded':
+            str1 += 'Errors:\n'
+            for item in result["errors"]:
+                str1 += '\t' + str(item) + '\n'
+
+        self.text.SetValue(str1)
+
 #===============================================================================
 # CONFIGURATION PANEL ON THE LEFT SIDE
 #===============================================================================
-        
+
+
 class MdEditConfigPanel(wx.Panel):
-    
+
+    '''Configuration pane for selection editing mode.
+    @var mapGrassEdit: True = editing metadata of GRASS maps, false= editing externally loaded xml and template
+    '''
+
     def __init__(self, parent):
         wx.Panel.__init__(self, parent, id=wx.ID_ANY)
         self.SetMinSize((240, -1))
         self.mapGrassEdit = True
-        
+
         self.rbGrass = wx.RadioButton(self, id=wx.ID_ANY, label='Metadata map editor', style=wx.RB_GROUP)
         self.rbExternal = wx.RadioButton(self, id=wx.ID_ANY, label='Metadata external editor')
-        
+
         self.comboBoxProfile = wx.ComboBox(self, choices=['INSPIRE', 'GRASS BASIC', 'Load Custom'])
         pub.subscribe(self.onComboboxDisable, "comboBoxProfile.disable")
         pub.subscribe(self.onComboboxEnable, "comboBoxProfile.enable")
@@ -699,23 +760,23 @@
         self.comboBoxProfile.SetStringSelection('GRASS BASIC')
 
         self.Bind(wx.EVT_RADIOBUTTON, self.onSetRadioType, id=self.rbGrass.GetId())
-        self.Bind(wx.EVT_RADIOBUTTON, self.onSetRadioType, id=self.rbExternal.GetId())  
-        self.comboBoxProfile.Bind(wx.EVT_COMBOBOX,self.onChangeComboBoxProfile )
-        
+        self.Bind(wx.EVT_RADIOBUTTON, self.onSetRadioType, id=self.rbExternal.GetId())
+        self.comboBoxProfile.Bind(wx.EVT_COMBOBOX, self.onChangeComboBoxProfile)
+
         self._layout()
-        
-    def onChangeComboBoxProfile(self,evt):
+
+    def onChangeComboBoxProfile(self, evt):
         pass
-    
+
     def onComboboxDisable(self):
         self.comboBoxProfile.Disable()
-        
+
     def onComboboxEnable(self):
-        self.comboBoxProfile.Enable()     
-        
-    def onSetProfile(self,profile):
+        self.comboBoxProfile.Enable()
+
+    def onSetProfile(self, profile):
         self.comboBoxProfile.SetStringSelection(profile)
-        
+
     def SetVal(self, event):
         state1 = str()
         state2 = str(self.rb2.GetValue())
@@ -729,197 +790,198 @@
             self.comboBoxProfile.Hide()
         else:
             self.comboBoxProfile.Show()
-        pub.sendMessage('EDITING_MODE.update',editStatus=self.mapGrassEdit)
+        pub.sendMessage('EDITING_MODE.update', editStatus=self.mapGrassEdit)
 
     def _layout(self):
         self.mainsizer = wx.BoxSizer(wx.VERTICAL)
         self.SetSizer(self.mainsizer)
         self.mainsizer.Add(self.rbGrass)
-        self.mainsizer.Add(self.rbExternal)        
-        self.mainsizer.Add(self.comboBoxProfile)       
+        self.mainsizer.Add(self.rbExternal)
+        self.mainsizer.Add(self.comboBoxProfile)
 #===============================================================================
 # TOOLBAR
 #===============================================================================
+
+
 class MdToolbar(wx.Panel):
 
-    def __init__(self, parent,jinjaPath,xmlPath,sb,mdDestionation):
+    '''Main toolbar of editor
+    '''
+
+    def __init__(self, parent, jinjaPath, xmlPath, sb, mdDestionation):
         wx.Panel.__init__(self, parent, id=wx.ID_ANY)
-        self.mdDestination=mdDestionation
-        self.batch=False
+        self.mdDestination = mdDestionation
+        self.batch = False
         self.jinjaPath = jinjaPath
-        self.statusBar=sb
+        self.statusBar = sb
         self.xmlPath = xmlPath
-        self.extendEdit=False
+        self.extendEdit = False
         self.toolbar = wx.ToolBar(self, 1, wx.DefaultPosition, (-1, -1))
+
         bitmapSave = wx.Image(
             os.path.join(os.environ['GISBASE'], 'gui', 'icons', 'grass', 'save.png'),
             wx.BITMAP_TYPE_PNG).ConvertToBitmap()
         bitmapNew = wx.Image(
             os.path.join(os.environ['GISBASE'], 'gui', 'icons', 'grass', 'create.png'),
-            wx.BITMAP_TYPE_PNG).ConvertToBitmap()      
+            wx.BITMAP_TYPE_PNG).ConvertToBitmap()
         bitmapLoad = wx.Image(
             os.path.join(os.environ['GISBASE'], 'gui', 'icons', 'grass', 'open.png'),
-            wx.BITMAP_TYPE_PNG).ConvertToBitmap()   
+            wx.BITMAP_TYPE_PNG).ConvertToBitmap()
         bitmaSettings = wx.Image(
             os.path.join(os.environ['GISBASE'], 'gui', 'icons', 'grass', 'settings.png'),
-            wx.BITMAP_TYPE_PNG).ConvertToBitmap()    
-#-------------------------------------------------------------------- EDIT 
+            wx.BITMAP_TYPE_PNG).ConvertToBitmap()
+#-------------------------------------------------------------------- EDIT
         self.toolbar.AddSeparator()
         bitmapEdit = wx.Image(
             os.path.join(os.environ['GISBASE'], 'gui', 'icons', 'grass', 'edit.png'),
             wx.BITMAP_TYPE_PNG).ConvertToBitmap()
         self.bttEdit = BitmapBtnTxt(
-            self.toolbar, -1, bitmapEdit,'edit' )
+            self.toolbar, -1, bitmapEdit, 'edit')
         self.toolbar.AddControl(control=self.bttEdit)
         self.bttEdit.Disable()
-
 #-------------------------------------------------------------------- NEW SESION
         self.toolbar.AddSeparator()
-        self.bttNew = BitmapBtnTxt(
-            self.toolbar, -1,bitmapNew,'session')
+        self.bttNew = BitmapBtnTxt(self.toolbar, -1, bitmapNew, 'session')
         self.toolbar.AddControl(control=self.bttNew)
         self.bttNew.Disable()
 #-------------------------------------------------------------------------- SAVE
-
         self.bttsave = BitmapBtnTxt(self.toolbar, -1, bitmapSave, "XML")
         self.bttsave.Disable()
         self.toolbar.AddControl(control=self.bttsave)
-        self.toolbar.AddSeparator()        
-
+        self.toolbar.AddSeparator()
 #----------------------------------------------------------------- OPEN TEMPLATE
         self.bttLoad = BitmapBtnTxt(self.toolbar, -1, bitmapLoad, "template", size=(100, -1))
         self.toolbar.AddControl(control=self.bttLoad)
         self.bttLoad.Disable()
-
 #---------------------------------------------------------------------- OPEN XML
         self.bttLoadXml = BitmapBtnTxt(self.toolbar, -1, bitmapLoad, "XML")
         self.toolbar.AddControl(control=self.bttLoadXml)
-        self.bttLoadXml.Disable()     
-
+        self.bttLoadXml.Disable()
         self.toolbar.AddSeparator()
-        self.toolbar.AddSeparator()
 #-------------------------------------------------------------------- NEW TEMPLATE
         self.bttCreateTemplate = BitmapBtnTxt(self.toolbar, -1, bitmapNew, "template", size=(100, -1))
         self.toolbar.AddControl(control=self.bttCreateTemplate)
         self.bttCreateTemplate.Disable()
-        
 #-------------------------------------------------------------------------- SAVE
         self.bttSaveTemplate = BitmapBtnTxt(self.toolbar, -1, bitmapSave, "template", size=(100, -1))
         self.bttSaveTemplate.Disable()
         self.toolbar.AddControl(control=self.bttSaveTemplate)
-        self.toolbar.AddSeparator()         
+        self.toolbar.AddSeparator()
 #-------------------------------------------------------------------------- SAVE
-
         self.bttUpdateGRASS = BitmapBtnTxt(self.toolbar, -1, bitmapSave, "GRASS", size=(100, -1))
         self.bttUpdateGRASS.Disable()
         self.toolbar.AddControl(control=self.bttUpdateGRASS)
-        self.toolbar.AddSeparator()         
-        #self.toolbar.AddSeparator()                
+        self.toolbar.AddSeparator()
 #-------------------------------------------------------------------------- Config
-
         self.bttConfig = BitmapBtnTxt(self.toolbar, -1, bitmaSettings, "workdir", size=(100, -1))
-        #self.bttConfig.Disable()
         self.toolbar.AddControl(control=self.bttConfig)
-        self.toolbar.AddSeparator() 
+        self.toolbar.AddSeparator()
 
         self.toolbar.Realize()
         self._layout()
 
-        
         self.bttLoad.Bind(wx.EVT_BUTTON, self.OnLoadTemplate)
         pub.subscribe(self.onBttSaveEnable, "bttLoad.enable")
         pub.subscribe(self.onBttSaveDisable, "bttLoad.disable")
-        
+
         self.bttsave.Bind(wx.EVT_BUTTON, self.onSaveXML)
         pub.subscribe(self.onBttLoadEnable, "bttSave.enable")
         pub.subscribe(self.onBttLoadDisable, "bttSave.disable")
-                
+
         self.bttLoadXml.Bind(wx.EVT_BUTTON, self.onLoadXml)
         pub.subscribe(self.onBttLoadXmlEnable, "bttLoadXml.enable")
         pub.subscribe(self.onBttLoadXmlDisable, "bttLoadXml.disable")
-                
+
         self.bttNew.Bind(wx.EVT_BUTTON, self.onNewSession)
         pub.subscribe(self.onBttNewEnable, "bttNew.enable")
         pub.subscribe(self.onBttNewDisable, "bttNew.disable")
-        
+
         self.bttEdit.Bind(wx.EVT_BUTTON, self.onEdit)
         pub.subscribe(self.onBtEditEnable, "bttEdit.enable")
         pub.subscribe(self.onBttEditDisable, "bttEdit.disable")
-                
+
         self.bttCreateTemplate.Bind(wx.EVT_BUTTON, self.onCreateTemplate)
         pub.subscribe(self.onBttCreateTemplateEnable, "bttCreateTemplate.enable")
-        pub.subscribe(self.onBttCreateTemplateDisable, "bttCreateTemplate.disable")       
-         
-        self.bttSaveTemplate.Bind(wx.EVT_BUTTON,self.onSaveTemplate)
+        pub.subscribe(self.onBttCreateTemplateDisable, "bttCreateTemplate.disable")
+
+        self.bttSaveTemplate.Bind(wx.EVT_BUTTON, self.onSaveTemplate)
         pub.subscribe(self.onBttSaveTemplateEnable, "bttSaveTemplate.enable")
-        pub.subscribe(self.onBttSaveTemplateDisable, "bttSaveTemplate.disable")   
-        
-        self.bttUpdateGRASS.Bind(wx.EVT_BUTTON,self.onUpdateGRASS)
+        pub.subscribe(self.onBttSaveTemplateDisable, "bttSaveTemplate.disable")
+
+        self.bttUpdateGRASS.Bind(wx.EVT_BUTTON, self.onUpdateGRASS)
         pub.subscribe(self.onBttUpdateGRASSEnable, "bttSaveTemplate.enable")
-        pub.subscribe(self.onBttUpdateGRASSDisable, "bttSaveTemplate.disable")           
-    
-        self.bttConfig.Bind(wx.EVT_BUTTON,self.onSettings)
-        
+        pub.subscribe(self.onBttUpdateGRASSDisable, "bttSaveTemplate.disable")
 
+        self.bttConfig.Bind(wx.EVT_BUTTON, self.onSettings)
+
     def onBttSaveDisable(self):
         self.bttSave.Disable()
+
     def onBttSaveEnable(self):
-        self.bttSave.Enable()   
-                  
+        self.bttSave.Enable()
+
     def onBttLoadDisable(self):
         self.bttLoad.Disable()
+
     def onBttLoadEnable(self):
-        self.bttLoad.Enable()        
-   
+        self.bttLoad.Enable()
+
     def onBttLoadXmlDisable(self):
         self.bttLoadXml.Disable()
+
     def onBttLoadXmlEnable(self):
-        self.bttLoadXml.Enable()    
-   
+        self.bttLoadXml.Enable()
+
     def onBttNewDisable(self):
         self.bttNew.Disable()
+
     def onBttNewEnable(self):
-        self.bttNew.Enable()           
-                  
+        self.bttNew.Enable()
+
     def onBttEditDisable(self):
         self.bttEdit.Disable()
+
     def onBtEditEnable(self):
-        self.bttEdit.Enable()    
-                       
+        self.bttEdit.Enable()
+
     def onBttCreateTemplateDisable(self):
         self.bttCreateTemplate.Disable()
+
     def onBttCreateTemplateEnable(self):
-        self.bttCreateTemplate.Enable() 
-        
+        self.bttCreateTemplate.Enable()
+
     def onBttSaveTemplateDisable(self):
         self.bttSaveTemplate.Disable()
+
     def onBttSaveTemplateEnable(self):
-        self.bttSaveTemplate.Enable() 
+        self.bttSaveTemplate.Enable()
 
     def onBttUpdateGRASSDisable(self):
         self.bttUpdateGRASS.Disable()
+
     def onBttUpdateGRASSEnable(self):
-        self.bttUpdateGRASS.Enable() 
-     
-    def onUpdateGRASS(self,evt):
-        pub.sendMessage('GRASS_METADATA.update')     
-                                
+        self.bttUpdateGRASS.Enable()
 
-    def onSettings(self,evt):
-        
-            dlg = wx.DirDialog(self, 
-                               message="Choose metadata working directory",
-                               defaultPath=self.mdDestination, 
-                               style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
-            
-            if dlg.ShowModal() == wx.ID_OK:
-                self.mdDestination=dlg.GetPath()
-                pub.sendMessage('MD_DESTINATION.update',value=self.mdDestination)
-                dlg.Destroy()
-            
-            GMessage( 'Metadata destinatnion: %s'%self.mdDestination)        
-                
+    def onUpdateGRASS(self, evt):
+        pub.sendMessage('GRASS_METADATA.update')
+
+    def onSettings(self, evt):
+        dlg = wx.DirDialog(self,
+                           message="Select metadata working directory",
+                           defaultPath=self.mdDestination,
+                           style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
+
+        if dlg.ShowModal() == wx.ID_OK:
+            self.mdDestination = dlg.GetPath()
+            pub.sendMessage('MD_DESTINATION.update', value=self.mdDestination)
+            dlg.Destroy()
+
+        GMessage('Metadata destinatnion: %s' % self.mdDestination)
+
     def hideMultipleEdit(self):
+        '''Multiple editor is off
+        '''
+
         self.bttLoad.Hide()
         self.bttLoadXml.Hide()
         self.bttNew.Hide()
@@ -927,160 +989,161 @@
         self.bttCreateTemplate.Hide()
         self.bttSaveTemplate.Hide()
         self.bttUpdateGRASS.Hide()
-          
+
     def showMultipleEdit(self):
+        '''Multiple editor is on
+        '''
         self.bttLoad.Show()
         self.bttLoadXml.Show()
         self.bttNew.Show()
         self.bttEdit.Show()
         self.bttCreateTemplate.Show()
-        self.bttSaveTemplate.Show()   
-        self.bttUpdateGRASS.Show()     
-                   
-    def onCreateTemplate(self,evt):
-        pub.sendMessage('TEMPLATE_EDITOR_STATUS.update',value=True)
+        self.bttSaveTemplate.Show()
+        self.bttUpdateGRASS.Show()
+
+    def onCreateTemplate(self, evt):
+        pub.sendMessage('TEMPLATE_EDITOR_STATUS.update', value=True)
         self.onEdit(evt=None)
         self.bttCreateTemplate.Disable()
         self.bttSaveTemplate.Enable()
-        
-    def onEdit(self,evt=None):
-       #print self.GetParent().configPanelLeft.rbGrass.GetValue()
+
+    def onEdit(self, evt=None):
+        '''
+        @var : extendEdit if xml and jinja is loaded from file
+        '''
         if self.extendEdit:
-            pub.sendMessage('SET_JINJA_AND_XML.update',jinja=self.jinjaPath,xml=self.xmlPath)
+            pub.sendMessage('SET_JINJA_AND_XML.update', jinja=self.jinjaPath, xml=self.xmlPath)
             self.bttUpdateGRASS.Disable()
-            
-        if self.GetParent().configPanelLeft.rbGrass.GetValue(): 
-            ok=self.GetParent().onEditMapMetadata()
+
+        if self.GetParent().configPanelLeft.rbGrass.GetValue():
+            ok = self.GetParent().onEditMapMetadata()
             if not ok:
                 return
         else:
             pub.sendMessage('INIT_EDITOR.create')
-            
+
         self.bttCreateTemplate.Disable()
         self.bttEdit.Disable()
         self.bttsave.Enable()
         if not self.extendEdit:
             self.bttUpdateGRASS.Enable()
-            
-        try:
-            if self.GetParent().numOfMap>1:
+
+        try:  # if  multiediting mode ON
+            if self.GetParent().numOfMap > 1:
                 XMLhead, XMLtail = os.path.split(self.xmlPath)
-                self.batch=mdutil.yesNo(self, 'Do you want to save metadata of : %s without editing ? '%XMLtail)
+                self.batch = mdutil.yesNo(self, 'Do you want to save metadata of : %s without editing ? ' % XMLtail, 'Multiple editing')
             if self.batch:
                 self.onSaveXML()
         except:
             pass
-        
+
     def onNewSession(self, evt):
         pub.sendMessage('INIT_EDITOR.create')
-        pub.sendMessage('TEMPLATE_EDITOR_STATUS.update',value=False,template=False)
+        pub.sendMessage('TEMPLATE_EDITOR_STATUS.update', value=False, template=False)
+        # chck current editing mode(grass or external xml editor)
         if self.GetParent().configPanelLeft.rbGrass is False:
             self.bttLoad.Enable()
-            self.bttLoadXml.Enable() 
+            self.bttLoadXml.Enable()
         self.bttsave.Disable()
         self.bttUpdateGRASS.Disable()
-        self.jinjaPath=None
-        self.xmlPath=None
+        self.jinjaPath = None
+        self.xmlPath = None
         self.bttsave.SetLabel('XML')
         self.showMultipleEdit()
-        
+
         self.bttSaveTemplate.Disable()
-        
+
     def onChangeXmlorTemplate(self, evt=None):
+        '''in case if path of template and xml path are initialized-> enable buttons for next step
+        '''
         if self.jinjaPath is not None and self.xmlPath is not None:
             pub.sendMessage('HIDE_LEFT_PANEL.update')
             self.bttEdit.Enable()
             self.bttCreateTemplate.Enable()
             self.bttLoad.Disable()
-            self.bttLoadXml.Disable() 
-            self.extendEdit=True
-               
+            self.bttLoadXml.Disable()
+            self.extendEdit = True
+
     def onLoadXml(self, evt=None):
-        dlg = wx.FileDialog(
-                            self,
-                            "Choose a xml metadata file",
+        dlg = wx.FileDialog(self,
+                            "Select xml metadata file",
                             self.mdDestination,
                             "",
                             "*.xml",
                             wx.OPEN)
+
         if dlg.ShowModal() == wx.ID_OK:
             self.xmlPath = dlg.GetPath()
-            #self.GetParent().xmlPath = self.xmlPath
-            tx=self.statusBar.GetStatusText()
-            self.statusBar.SetStatusText(tx + '  Selected XML: '+ self.xmlPath )
+            tx = self.statusBar.GetStatusText()
+            self.statusBar.SetStatusText(tx + '  Selected XML: ' + self.xmlPath)
             self.onChangeXmlorTemplate()
             dlg.Destroy()
 
-    def onSaveTemplate(self,evt=None):
-        dlg = wx.FileDialog(
-                            self,
-                            "Choose a file",
+    def onSaveTemplate(self, evt=None):
+        dlg = wx.FileDialog(self,
+                            "Select output file",
                             self.mdDestination,
                             "",
                             "*.xml",
                             wx.SAVE)
-        
+
         if dlg.ShowModal() == wx.ID_OK:
+            pub.sendMessage('EXPORT_TEMPLATE.create',
+                            outPath=dlg.GetDirectory(),
+                            outFileName=dlg.GetFilename())
 
-            pub.sendMessage('EXPORT_TEMPLATE.create',outPath=dlg.GetDirectory(),
-                                                    outFileName=dlg.GetFilename()) 
-                        
     def OnLoadTemplate(self, evt):
-            dlg = wx.FileDialog(
-                                self,
-                                "Choose template",
-                                self.mdDestination,
-                                "",
-                                "*.xml",
-                                wx.OPEN)
-            
-            if dlg.ShowModal() == wx.ID_OK:
-                    self.jinjaPath = dlg.GetPath()
-                    tx= self.statusBar.GetStatusText()
-                    self.statusBar.SetStatusText(tx+' Selected template: '+ self.jinjaPath)            
-                    self.onChangeXmlorTemplate()
+        dlg = wx.FileDialog(self,
+                            "Select template of ISO profile",
+                            self.mdDestination,
+                            "",
+                            "*.xml",
+                            wx.OPEN)
 
-            dlg.Destroy()        
-                    
+        if dlg.ShowModal() == wx.ID_OK:
+            self.jinjaPath = dlg.GetPath()
+            tx = self.statusBar.GetStatusText()
+            self.statusBar.SetStatusText(tx + ' Selected template: ' + self.jinjaPath)
+            self.onChangeXmlorTemplate()
+
+        dlg.Destroy()
+
     def onSaveXML(self, evt=None):
-            self.XMLhead, self.XMLtail = os.path.split(self.xmlPath)
-            if not self.batch:#if normal saving with user-task-dialog
-                
-                dlg = wx.FileDialog(self,
+        self.XMLhead, self.XMLtail = os.path.split(self.xmlPath)
+        if not self.batch:  # if normal saving with user-task-dialog
+
+            dlg = wx.FileDialog(self,
                                 message="Set output file",
                                 defaultDir=self.mdDestination,
                                 defaultFile=self.XMLtail,
                                 wildcard="*.xml",
-                                style=wx.SAVE|wx.FD_OVERWRITE_PROMPT)
-                
-                if dlg.ShowModal() == wx.ID_OK:
-                    pub.sendMessage('EXPORT_XML.create',outPath=dlg.GetDirectory(),outFileName=dlg.GetFilename())
-                    if self.bttsave.GetLabelText() =='next':
-                        pub.sendMessage('EDIT_MAP_METADATA.create',multipleEditing=True)
-                        
-                else:
-                    if self.bttsave.GetLabelText() =='next':
-                        ask=mdutil.yesNo(self,'File is not saved. Do you want to save it? ')
-                        if ask:
-                            self.onSaveXML() 
-                        pub.sendMessage('EDIT_MAP_METADATA.create',multipleEditing=True)
-                        
-                    else:              
-                        GMessage('File not save.' )        
-                dlg.Destroy()
-                
+                                style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
+
+            if dlg.ShowModal() == wx.ID_OK:
+                pub.sendMessage('EXPORT_XML.create', outPath=dlg.GetDirectory(), outFileName=dlg.GetFilename())
+                if self.bttsave.GetLabelText() == 'next':
+                    pub.sendMessage('EDIT_MAP_METADATA.create', multipleEditing=True)
+
             else:
-                pub.sendMessage('EXPORT_XML.create',outPath=None,outFileName=None)
-                pub.sendMessage('EDIT_MAP_METADATA.create',multipleEditing=True)
+                if self.bttsave.GetLabelText() == 'next':
+                    ask = mdutil.yesNo(self, 'File is not saved. Do you want to save it? ', 'Save dialog')
+                    if ask:
+                        self.onSaveXML()
+                    pub.sendMessage('EDIT_MAP_METADATA.create', multipleEditing=True)
 
+                else:
+                    GMessage('File not save.')
+            dlg.Destroy()
+
+        else:
+            pub.sendMessage('EXPORT_XML.create', outPath=None, outFileName=None)
+            pub.sendMessage('EDIT_MAP_METADATA.create', multipleEditing=True)
+
     def _layout(self):
         self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
         self.SetSizer(self.mainsizer)
         self.mainsizer.Add(self.toolbar)
-             
-#------------------------------------------------------------------------------ 
 
-
 #----------------------------------------------------------------------
 if __name__ == "__main__":
     app = wx.App(False)

Modified: sandbox/krejcmat/src/jinjainfo.py
===================================================================
--- sandbox/krejcmat/src/jinjainfo.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/jinjainfo.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,28 +1,55 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
 """
-MODULE:    g.gui.metadata
+ at package jinjainfo
+ at module g.gui.metadata
+ at brief  Library for parsing informations from jinja template
 
-AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+Classes:
+ - jinjainfo::MdDescription
+ - jinjainfo::JinjaTemplateParser
 
-PURPOSE:   Module for editing metadata based on ISO
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
 
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
-
-           This program is free software under the GNU General Public
-           License (>=v2). Read the file COPYING that comes with GRASS
-           for details.
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
+from core.gcmd import GError
+from mdutil import findBetween
 
-import os
-from jinja2             import Environment, FileSystemLoader
-from gi.overrides.GLib  import GError
 
 class MdDescription():
 
+    '''Object which is initialzed by jinja template in '{# #}'
+    '''
+
     def __init__(self, tag=None, object=None, name='', desc=None,
-                 example=None, type=None, multi=0, inboxmulti=None, group=None,
-                 inbox=None, multiline=None, validator=None, num=None, ref=None,selfInfoString=None):
+                 example=None, type=None, multi=0, inboxmulti=None,
+                 group=None, inbox=None, multiline=None, validator=None,
+                 num=None, ref=None, selfInfoString=None):
+        '''
+        @param tag: OWSLib object which will be replaced by value of object after jinja template system render new file
+        @param object: some object in OWSLib is neecesarry to initialize temporaly in gui generator. Others are initialize by configure file
+        @param name:  label and tooltip name
+        @param desc: description/definition of metadata item
+        @param example: example of md item (tooltip)
+        @param type: data type is neccesary to validet widgets
+        @param multi: 0=only one instance of editor::MdItem widget can be, 1= multiple insctances of widgets can be
+        @param inboxmulti: 0=static box of items has not button for duplicating self 1=has button
+        @param group: this param initialize page in notebook in mani editor
+        @param inbox: Every items in block of code in jinja template must have same value of inbox.
+               The value of inbox representing label of static box in gui.
+        @param multiline: If true- textCtrl widget will be init with multiline control
+        @param validator: Not use currently
+        @param ref: additional information about reference of metadata item (ISO reference)
+        @param selfInfoString: string value representing all these information. (parsed from jinja template)
+        @var mdItem: very important parametr which holds instances of widgets(editor::MdItem)
+             on every index of list is one instance of widget. In case, if is in static box MdItem with duplicating button:
+            index of list is represented by list of these items
+        @var statements: hold information about first statement in block
+        @var statements1: hold info about secont stetement in block of var: statement
+        '''
         self.tag = tag
         self.object = object
         self.name = name
@@ -32,9 +59,9 @@
         self.multiplicity = multi  # multiplicity of MD item
         self.group = group
         self.inbox = inbox
-        self.ref=ref
-        self.selfInfoString=selfInfoString
-        # multiplicity in subrotoup (in static box)
+        self.ref = ref
+        self.selfInfoString = selfInfoString
+
         self.inboxmulti = inboxmulti
         self.multiline = multiline  # type of ctrl text
         self.validator = validator
@@ -42,14 +69,13 @@
 
         self.statements = None
         self.statements1 = None
-        self.num = num
         self.mdItem = list()
 
     def addMdItem(self, newMdItem, oldMdItem=None):
-        '''list of objects MdItem()
+        '''care about integrity of var: self.mdItem
         '''
         # if new mditem is from box- need to hold information
-        # about it.(list on same index in self.mdItem)
+        # about it.(list on the same index in self.mdItem)
         if oldMdItem is not None:
             for n, item in enumerate(self.mdItem):
                 for i in item:
@@ -58,8 +84,9 @@
         else:
             self.mdItem.append(newMdItem)
 
-
     def removeMdItem(self, item):
+        '''care about integrity of var: self.mdItem
+        '''
         try:
             for k, oldListItem in enumerate(self.mdItem):
                 for i in oldListItem:
@@ -77,12 +104,20 @@
             self.statements1 = stat
 
 
-class JinjaTemplateInfo():
+class JinjaTemplateParser():
 
+    '''Parser of OWSLib tag and init. values of jinjainfo::MdDescription from jinja template.
+    '''
+
     def __init__(self, template):
-
-        self.mdDescription = []  # list of object MdDescription
-        self.mdOWSTag = []  # list of object in jinja template
+        '''
+        @var mdDescription: list of jinjainfo::mdDescription
+        @var mdOWSTag: list of tags in jinja templates
+        @var mdOWSTagStr: string representing OWSLib tags from template(per line)
+        @var mdOWSTagStrList:  on each index of list is one line with parsed OWSLib tag
+        '''
+        self.mdDescription = []
+        self.mdOWSTag = []
         self.template = template
 
         self.mdOWSTagStr = ''
@@ -90,86 +125,68 @@
 
         self._readJinjaInfo()
         self._readJinjaTags()
-        self._domdOWSTagStr()
+        self._formatMdOWSTagStrToPythonBlocks()
 
-    def cretemdDescriptionDict(self, akey):
-        box = {}
-        for md in self.mdDescription:
-            skey = 'md.' + str(akey)
-            key = eval(skey)
-            if key is not None:
-                if key not in box:
-                    box.setdefault(key, [])
-                box[key].append(md)
-        return box
-
-    def _domdOWSTagStr(self):
-        self.mdOWSTagStr = ""
-        tab = 0
-        for item in self.mdOWSTag:
-            if str(item).find(" endfor ") != -1 or \
-                    str(item).find(" endif ") != -1 or \
-                    str(item).find(" endwhile ") != -1:
-                tab -= 1
-                continue
-
-            tabstr = '\t' * tab
-            str1 = tabstr + item[1:] + '\n'
-            self.mdOWSTagStr += str1
-            self.mdOWSTagStrList.append(tabstr + item[1:])
-
-            if str(item).find(" for ") != -1  \
-                       or str(item).find(" if ") != -1  \
-                       or str(item).find(" while ") != -1:
-                tab += 1
-
     def _readJinjaTags(self):
+        '''Parser of OWSLib tag from jinja template to list
+        '''
         try:
             with open(self.template, "r") as f:
                 for line in f:
 
                     # if found start of comments
                     if str(line).find("{{") != -1:
-                        object = self._findBetween(line, "{{", "}}")
-                        self.mdOWSTag.append(object)
+                        obj = findBetween(line, "{{", "}}")
+                        self.mdOWSTag.append(obj)
 
                     if str(line).find("{%") != -1:
-                        object = self._findBetween(line, "{%", "-%}")
-                        self.mdOWSTag.append(object)
+                        obj = findBetween(line, "{%", "-%}")
+                        self.mdOWSTag.append(obj)
 
-        except IOError as e:
+        except:
             GError('Cannot open jinja template')
-            #print "I/O error({0}): {1}".format(e.errno, e.strerror)
+            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
 
     def _readJinjaInfo(self):
-        counter = 1
+        '''Parser  of 'comments'({# #}) in jinja template which are represented by jinjainfo::MdDescription
+        parsed values initializing list of jinjainfo::MdDesctiption obect
+        '''
         try:
             with open(self.template, "r") as f:
                 for line in f:
                     # if found start of comments
                     if str(line).find("{#") != -1:
-                        values = self._findBetween(line, "{#", "#}")
-                        values += ',num=' + str(counter)
-                        values1 =self._findBetween(line, "{%", "#}")
-                        values2 =self._findBetween(line, "{{", "#}")
-                        if values1 !='':
-                            values+=",selfInfoString='''{%"+values1+"#}'''"
+                        values = findBetween(line, "{#", "#}")
+                        values1 = findBetween(line, "{%", "#}")
+                        values2 = findBetween(line, "{{", "#}")
+                        if values1 != '':
+                            values += ",selfInfoString='''{%" + values1 + "#}'''"
                         else:
-                            values+=",selfInfoString='''{{"+values2+"#}'''"
-                            
+                            values += ",selfInfoString='''{{" + values2 + "#}'''"
+
                         exe_str = "self.mdDescription.append(MdDescription(%s))" % values
-                        exe_str=exe_str.decode("utf-8",'ignore')
+                        exe_str = exe_str.decode("utf-8", 'ignore')
                         eval(exe_str)
-                        counter += 1
-        except IOError as e:
+        except:
             GError('Cannot open jinja template')
-            #print "I/O error({0}): {1}".format(e.errno, e.strerror)
-           
-    def _findBetween(self, s, first, last):
-        try:
-            start = s.index(first) + len(first)
-            end = s.index(last, start)
-            return s[start:end]
-        except ValueError:
-            return ""
+            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
 
+    def _formatMdOWSTagStrToPythonBlocks(self):
+        '''Formating of parsed tags to pythonic blocks
+        '''
+        self.mdOWSTagStr = ""
+        tab = 0
+        for item in self.mdOWSTag:
+            if str(item).find(" endfor ") != -1 or \
+                    str(item).find(" endif ") != -1:
+                tab -= 1
+                continue
+
+            tabstr = '\t' * tab
+            str1 = tabstr + item[1:] + '\n'
+            self.mdOWSTagStr += str1
+            self.mdOWSTagStrList.append(tabstr + item[1:])
+
+            if str(item).find(" for ") != -1  \
+                    or str(item).find(" if ") != -1:
+                tab += 1

Modified: sandbox/krejcmat/src/mdgrass.py
===================================================================
--- sandbox/krejcmat/src/mdgrass.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/mdgrass.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,65 +1,69 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
-
 """
-MODULE:    v.info.iso, r.info.iso, g.gui.metadata 
+ at package mdgrass
+ at module  v.info.iso, r.info.iso, g.gui.metadata
+ at brief   Base class for import(r.info,v.info) and export(r/v.support)
+         metadata with using OWSLib and jinja template.
 
-AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+Classes:
+ - mdgrass::MdDescription
 
-PURPOSE:   Module for creating metadata based on EN ISO 19115 and EN ISO 19119
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
 
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
-
-           This program is free software under the GNU General Public
-           License (>=v2). Read the file COPYING that comes with GRASS
-           for details.
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
-
 from owslib.iso import *
-from jinja2     import Environment, FileSystemLoader
+from jinja2 import Environment, FileSystemLoader
 
-from   lxml import etree
-import os,sys,re
+from lxml import etree
+import os
+import sys
+import re
 import StringIO
 import subprocess as sub
 import uuid
-import mdutil #metadata lib
+import mdutil  # metadata lib
 import getpass  # whoami for linux and  ms-win
 
 from grass.pygrass.modules.shortcuts import general as g
-from grass.pygrass.gis               import Mapset
-from grass.pygrass                   import raster
-from grass.pygrass.modules           import Module
-from grass.script                    import parse_key_val
-from subprocess                      import PIPE
-from datetime                        import date, datetime
-from grass.script                    import parser
-from grass.script                    import core as grass
+from grass.pygrass.gis import Mapset
+from grass.pygrass import raster
+from grass.pygrass.modules import Module
+from grass.script import parse_key_val
+from subprocess import PIPE
+from datetime import date, datetime
+from grass.script import parser
+from grass.script import core as grass
 
 
-
 class GrassMD():
 
+    '''
+    @var self.map:  name of choosen map by user
+    @var self.type: typ of map representation(cell, vector, r3)
+    @var md_grass:  dict with metadata from r.info v.info  except "r.info flag=h"
+
+    '''
+
     def __init__(self, map, type):
+        self.map = map
+        self.type = type
 
-        self.map = map  # name of choosen map by user
-
-        self.type = type  # typ of map representation(cell, vector, r3)
         self.isMapExist()  # function to check if map exist
-        # dict with metadata from r.info v.info  except "r.info flag=h"
         self.md_grass = {}
-        # create abstract from self.md_grass - key: source1, source2 and
-        # descriptio etc.
         self.md_abstract = ''
         self.md_vinfo_h = ''  # v.info flag=h" - parse
         self.gisenv_grass = grass.gisenv()  # dict with gisenv information
         # postfix of output xml file (variables)
-        self.schema_type = '_basic.xml'
+        self.schema_type = '_basic.xml'  # currently
         self.dirpath = os.path.dirname(os.path.realpath(__file__))
         # metadata object from OWSLIB ( for define md values)
         self.md = MD_Metadata(md=None)
         self.template = None  # path to file with xml templates
-        
+
         if self.type == "cell":
             self.parseRast()
         elif self.type == "vector":
@@ -72,38 +76,34 @@
         '''Check if is the map in working mapset'''
         self.mapset = grass.find_file(self.map, self.type)['mapset']
         if not self.mapset:
-            grass.fatal(_("Map <%s> doesn't exist")%self.map)
+            grass.fatal(_("Map <%s> doesn't exist") % self.map)
 
-    def readXML(self, xml_file):
-        '''create instance of metadata(owslib) from xml file'''
-        #print xml_file
-        self.md = MD_Metadata(etree.parse(xml_file))
-        
     def parseRast3D(self):
         pass
 
     def parseVect(self):
         '''Read metadata from v.info
-        #self.md_grass dictionary of metadata from v.info '''
+        @var self.md_grass dictionary of metadata from v.info
+        '''
 
         # parse md from v.info flags=-g -e -t
         vinfo = Module(
-                        'v.info',
-                        self.map,
-                        flags='get',
-                        quiet=True,
-                        stdout_=PIPE)
-        
+            'v.info',
+            self.map,
+            flags='get',
+            quiet=True,
+            stdout_=PIPE)
+
         self.md_grass = parse_key_val(vinfo.outputs.stdout)
 
         # parse md from v.info flag h (history of map in grass)
         rinfo_h = Module(
-                        'v.info',
-                        self.map,
-                        flags='h',
-                        quiet=True,
-                        stdout_=PIPE)
-        
+            'v.info',
+            self.map,
+            flags='h',
+            quiet=True,
+            stdout_=PIPE)
+
         md_h_grass = rinfo_h.outputs.stdout
         buf = StringIO.StringIO(md_h_grass)
         line = buf.readline().splitlines()
@@ -113,15 +113,16 @@
             line = buf.readline().splitlines()
         buf.close()
 
-        # change grass generated date format to iso format
+        # convert grass parsed date format to iso format
         # if date format is diverse from standard, use them
         self._createISODate('source_date')
 
     def _createISODate(self, key):
-        '''Function for convert grass-generated date to iso format
-           if the format of date is different to grass-generated format - use them and print warning  '''
+        '''Function for converting grass-generated date to iso format
+           if the format of date is different to grass-generated format - use them and print warning
+        '''
         try:
-            date = datetime.strptime(self.md_grass[key],'%a %b %d %H:%M:%S %Y')
+            date = datetime.strptime(self.md_grass[key], '%a %b %d %H:%M:%S %Y')
             self.md_grass['dateofcreation'] = date.strftime('%Y-%m-%d')
         except:
             grass.warning('date of creation: unknown date format')
@@ -132,13 +133,12 @@
         #self.md_grass       dictionary of metadata from v.info
         #self.md_abstract    string created by merge information from 'description' and 'source'
         '''
-        rinfo = Module(
-                        'r.info',
-                        self.map,
-                        flags='gre',
-                        quiet=True,
-                        stdout_=PIPE)
-                        
+        rinfo = Module('r.info',
+                       self.map,
+                       flags='gre',
+                       quiet=True,
+                       stdout_=PIPE)
+
         self.md_grass = parse_key_val(rinfo.outputs.stdout)
 
         # convert date to iso format
@@ -146,31 +146,31 @@
 
         # create abstract
         if self.md_grass['description'] != '""':
-            self.md_abstract = self.md_grass['description']+'; '
+            self.md_abstract = self.md_grass['description'] + '; '
         if self.md_grass['source1'] != '""':
-            self.md_abstract += self.md_grass['source1'] +'; '
+            self.md_abstract += self.md_grass['source1'] + '; '
         if self.md_grass['source2'] != '""':
-            self.md_abstract += self.md_grass['source2'] +'; '
-        self.md_abstract += 'Total cells: ' + self.md_grass['cells']+'; '
+            self.md_abstract += self.md_grass['source2'] + '; '
+        self.md_abstract += 'Total cells: ' + self.md_grass['cells'] + '; '
         self.md_abstract += 'A range of values: min: ' + \
             self.md_grass['min'] + '  max: ' + self.md_grass['max']
         self.md_abstract.translate(None, """&<>"'""")
-        
-    def createGrassBasicISO(self,template=None):
+
+    def createGrassBasicISO(self, template=None):
         '''Create basic/essential profile based on ISO
         - unknown values are filling by n = '$NULL'
         '''
         try:
-            self.md_grass['comments']=self.md_grass['comments'].replace('\n','; ')
+            self.md_grass['comments'] = self.md_grass['comments'].replace('\n', '; ')
         except:
             pass
-        
+
         n = '$NULL'
         # jinja templates
         if template is None:
-            self.template = 'templates/grassGRASSTemplateFinal.xml'
+            self.template = os.path.join('templates', 'basicTemplate.xml')
         else:
-            self.template= template
+            self.template = template
 
         # OWSLib md object
         self.md.identification = MD_DataIdentification()
@@ -182,10 +182,10 @@
         # Metadata on metadata
         val = CI_ResponsibleParty()
         val.organization = n
-        val.email=n
+        val.email = n
         val.role = n
         self.md.contact.append(val)
-        
+
         # Identification/Resource Title
         self.md.identification.title = mdutil.replaceXMLReservedChar(self.md_grass['title'])
         self.md.datestamp = mdutil.replaceXMLReservedChar(date.today().isoformat())
@@ -194,10 +194,10 @@
         self.md.identification.identtype = 'dataset'
 
         # Identification/Unique Resource Identifier
-        self.md.identifier = mdutil.replaceXMLReservedChar(str(uuid.uuid4()) )
+        self.md.identifier = mdutil.replaceXMLReservedChar(str(uuid.uuid4()))
         self.md.identification.uricode.append(n)
         self.md.identification.uricodespace.append(n)
-        
+
         # Geographic/BB
         self.md.identification.extent.boundingBox.minx = mdutil.replaceXMLReservedChar(self.md_grass['south'])
         self.md.identification.extent.boundingBox.maxx = mdutil.replaceXMLReservedChar(self.md_grass['north'])
@@ -217,9 +217,9 @@
         val.date = self.md_grass['dateofcreation']
         val.type = 'creation'
         self.md.identification.date.append(val)
-        
-        self.md.identification.uom.append('m')#TODO
-        
+
+        self.md.identification.uom.append('m')  # TODO
+
         # different metadata sources for vector and raster
         if self.type == 'cell':
             # Identification/Resource Abstract
@@ -229,38 +229,37 @@
 
             # Quality/Lineage
             try:
-                self.md.dataquality.lineage = mdutil.replaceXMLReservedChar(self.md_grass['comments']).replace('\n','\\n')
+                self.md.dataquality.lineage = mdutil.replaceXMLReservedChar(self.md_grass['comments']).replace('\n', '\\n')
             except:
                 grass.warning('Native metadata *flag=comments* not found, dataquality.lineage filled by $NULL')
                 self.md.dataquality.lineage = n
-            
-            self.md.identification.denominators.append(n)    
+
+            self.md.identification.denominators.append(n)
             # Organisation/Responsible Party:
             val = CI_ResponsibleParty()
-            val.organization = n #self.md_grass['creator']
+            val.organization = n  # self.md_grass['creator']
             val.role = n
-            val.email=n
+            val.email = n
             self.md.identification.contact.append(val)
 
         if self.type == 'vector':
-            
+
             # Identification/Resource Abstract
             # TODO not enough sources for crate abstarce
             self.md.identification.abstract = mdutil.replaceXMLReservedChar(self.md_grass['name'])
-            self.md.dataquality.lineage = mdutil.replaceXMLReservedChar(self.md_vinfo_h).replace('\n','\\n')
+            self.md.dataquality.lineage = mdutil.replaceXMLReservedChar(self.md_vinfo_h).replace('\n', '\\n')
 
-            
             self.md.identification.denominators.append(self.md_grass['scale'])
             # Organisation/Responsible Party:
             val = CI_ResponsibleParty()
-            val.organization = n#mdutil.replaceXMLReservedChar(getpass.getuser())
-            val.email=n
+            val.organization = n  # mdutil.replaceXMLReservedChar(getpass.getuser())
+            val.email = n
             val.role = n
             self.md.identification.contact.append(val)
-            
-        self.templatePathAbs=os.path.join(self.dirpath,self.template)
 
-    def createGrassInspireISO(self,template=None):
+        self.templatePathAbs = os.path.join(self.dirpath, self.template)
+
+    def createGrassInspireISO(self, template=None):
         '''Create valid INSPIRE profile and fill it as much as possible by GRASS metadata. Missing values is $NULL
         -create basic md profile and add INSPIRE mandatory attributes
         '''
@@ -269,16 +268,16 @@
 
         # create basic profile
         self.createGrassBasicISO()
-        
+
         if template is None:
-            self.template = 'templates/grassInspireTemplateFinal.xml'
+            self.template = os.path.join('templates', 'inspireTemplate.xml')
         else:
             self.template = template
 
         n = '$NULL'
-        
-        if len(self.md.identification.distance)==0:
-            self.md.identification.distance.append(n)#TODO
+
+        if len(self.md.identification.distance) == 0:
+            self.md.identification.distance.append(n)  # TODO
         # Classification/Topic Category
         self.md.identification.topiccategory.append(n)
         self.md.identification.resourcelanguage.append(n)
@@ -304,7 +303,7 @@
         val = CI_OnlineResource()
         val.url = n
         self.md.distribution.online.append(val)
-        
+
         # Conformity/Date
         self.md.dataquality.conformancedate.append(n)
         self.md.dataquality.conformancedatetype.append(n)
@@ -323,36 +322,26 @@
         self.md.identification.temporalextent_start = n
         self.md.identification.temporalextent_end = n
 
-        self.templatePathAbs=os.path.join(self.dirpath,self.template)
-        #print self.templatePathAbs
-      
-    def saveXML(self, path=None, xml_out_name=None,wxparent=None):
-        ''' Save custom record to ISO XML file'''
+        self.templatePathAbs = os.path.join(self.dirpath, self.template)
+        # print self.templatePathAbs
 
+    def readXML(self, xml_file):
+        '''create instance of metadata(owslib) from xml file'''
+        self.md = MD_Metadata(etree.parse(xml_file))
+
+    def saveXML(self, path=None, xml_out_name=None, wxparent=None, overwrite=False):
+        ''' Save init. record  of OWSLib objects to ISO XML file'''
+
         # if  output file name is None, use map name and add postfix
         if xml_out_name is None:
-            xml_out_name = self.type+'_'+str(self.map).partition('@')[0] #+ self.schema_type
+            xml_out_name = self.type + '_' + str(self.map).partition('@')[0]  # + self.schema_type
         if not xml_out_name.lower().endswith('.xml'):
             xml_out_name += '.xml'
-            
-#===============================================================================
-#         if not path:
-#             if self.type=='cell':
-# 
-#                 path=os.path.join( mdutil.pathToMapset(),'cellmd')
-#                 if not os.path.exists(path):
-#                     print os.makedirs(path)
-#             if self.type=='vector':
-#                 print self.map
-#                 path=os.path.join( mdutil.pathToMapset(),
-#                                    'vector',
-#                                    str(self.map).partition('@')[0],
-#                                    'metd')
-#===============================================================================
+
         if not path:
-                path=os.path.join( mdutil.pathToMapset(),'metadata')
-                if not os.path.exists(path):
-                    print os.makedirs(path)            
+            path = os.path.join(mdutil.pathToMapset(), 'metadata')
+            if not os.path.exists(path):
+                print os.makedirs(path)
         path = os.path.join(path, xml_out_name)
 
         # generate xml using jinja tempaltes
@@ -360,153 +349,175 @@
         env.globals.update(zip=zip)
         template = env.get_template(self.template)
         iso_xml = template.render(md=self.md)
-       
+
         # write xml to flat file
-        if os.path.isfile(path):
-            if mdutil.yesNo(wxparent, 'Metadata file is exist. Do you want to overwrite file: %s?' %path):
+        if wxparent != None:
+            if os.path.isfile(path):
+                if mdutil.yesNo(wxparent, 'Metadata file is exist. Do you want to overwrite file: %s?' % path, 'Overwrite dialog'):
+                    try:
+                        xml_file = open(path, "w")
+                        xml_file.write(iso_xml)
+                        xml_file.close()
+                        Module('g.message', message='metadata exported: \n\
+                                                     %s' % (str(path)))
+                    except IOError as e:
+                        print "I/O error({0}): {1}".format(e.errno, e.strerror)
+                        grass.fatal('error: cannot write xml to file')
+                return path
+            else:
                 try:
                     xml_file = open(path, "w")
                     xml_file.write(iso_xml)
                     xml_file.close()
                     Module('g.message', message='metadata exported: \n\
-                                                 %s' % (str(path)))
+                                                     %s' % (str(path)))
                 except IOError as e:
                     print "I/O error({0}): {1}".format(e.errno, e.strerror)
                     grass.fatal('error: cannot write xml to file')
-                    #sys.exit()
-            return path
+                    # sys.exit()
+                return path
         else:
-                try:
-                    xml_file = open(path, "w")
-                    xml_file.write(iso_xml)
-                    xml_file.close()
-                    Module('g.message', message='metadata exported: \n\
-                                                 %s' % (str(path)))
-                except IOError as e:
-                    print "I/O error({0}): {1}".format(e.errno, e.strerror)
-                    grass.fatal('error: cannot write xml to file')
-                    #sys.exit()
-                return path
-            
-    def validate_inspire(self):      
+            if os.path.isfile(path):
+                Module('g.message', message='Metadata file is exist: %s' % path)
+                if overwrite:
+                    try:
+                        xml_file = open(path, "w")
+                        xml_file.write(iso_xml)
+                        xml_file.close()
+                        Module('g.message', message='Metadata file has been overwritten')
+                    except IOError as e:
+                        print "I/O error({0}): {1}".format(e.errno, e.strerror)
+                        grass.fatal('error: cannot write xml to file')
+                        # sys.exit()
+                    return path
+                else:
+                    Module('g.message', message='For overwriting use flag -o')
+                    return False
+
+    def validate_inspire(self):
         return mdutil.isnpireValidator(self.md)
-        
-    def updateGrassMd(self,md):
-        if self.type == "vector":            
-            
-            if len(md.contact)>0:
-                _org=''
+
+    def validate_basic(self):
+        return mdutil.grassProfileValidator(self.md)
+
+    def updateGrassMd(self, md):
+        '''
+        Update some parameters in r/v.support. This part need revision#TODO
+        '''
+        if self.type == "vector":
+
+            if len(md.contact) > 0:
+                _org = ''
                 for co in md.contact:
-                    if co.organization!='':
-                        _org+=co.organization+', '
-                    if co.email!='':    
-                        _org+=co.email+', '
-                    if co.role!='':
-                        _org+=co.role+'; '
-                    
+                    if co.organization != '':
+                        _org += co.organization + ', '
+                    if co.email != '':
+                        _org += co.email + ', '
+                    if co.role != '':
+                        _org += co.role + '; '
+
                 Module('v.support',
                        map=self.map,
                        organization=_org,
-                       flags='r')     
-                
+                       flags='r')
+
             if md.identification.date is not None:
-                if len(md.identification.date)>0:
-                    for d in md.identification.date:             
-                        if d.type=='creation':
-                            _date=d.date
-                            
+                if len(md.identification.date) > 0:
+                    for d in md.identification.date:
+                        if d.type == 'creation':
+                            _date = d.date
+
                     Module('v.support',
                            map=self.map,
                            date=_date,
-                           flags='r')     
-                  
-            if md.identification.contact is not None:               
-                if len(md.identification.contact)>0:
-                    _person=md.identification.contact.organization.pop()
-                        
+                           flags='r')
+
+            if md.identification.contact is not None:
+                if len(md.identification.contact) > 0:
+                    _person = md.identification.contact.organization.pop()
+
                     Module('v.support',
                            map=self.map,
                            person=_person,
-                           flags='r')                   
-                    
+                           flags='r')
+
             if md.identification.title is not (None or ''):
-                _name=md.identification.title
+                _name = md.identification.title
                 Module('v.support',
                        map=self.map,
                        map_name=_name,
-                       flags='r')     
-    
-            if len( md.identification.denominators)>0:
-                _scale= md.identification.denominators.pop()
+                       flags='r')
+
+            if len(md.identification.denominators) > 0:
+                _scale = md.identification.denominators.pop()
                 try:
-                    _scale=int(_scale)
+                    _scale = int(_scale)
                     Module('v.support',
                            map=self.map,
                            scale=_scale,
-                           flags='r')        
+                           flags='r')
                 except:
                     pass
-                
-            if md.identification.keywords is not None or len(md.identification.keywords) > 0:           
-                _comments=''
-                for k in md.identification.keywords:  
+
+            if md.identification.keywords is not None or len(md.identification.keywords) > 0:
+                _comments = ''
+                for k in md.identification.keywords:
                     for kw in k["keywords"]:
-                        if kw!='':
-                            _comments+=kw + ', '
-                    if k["thesaurus"]["title"]!='':
-                        _comments+= k["thesaurus"]["title"] +', '
-                    if k["thesaurus"]["date"]!='':
-                         _comments+= k["thesaurus"]["date"]+', '
-                    if k['thesaurus']['datetype']!='':
-                        _comments+= k['thesaurus']['datetype'] +';'
-                        
+                        if kw != '':
+                            _comments += kw + ', '
+                    if k["thesaurus"]["title"] != '':
+                        _comments += k["thesaurus"]["title"] + ', '
+                    if k["thesaurus"]["date"] != '':
+                        _comments += k["thesaurus"]["date"] + ', '
+                    if k['thesaurus']['datetype'] != '':
+                        _comments += k['thesaurus']['datetype'] + ';'
+
                 Module('v.support',
-                           map=self.map,
-                           comment=_comments,
-                           flags='r')                  
-    
+                       map=self.map,
+                       comment=_comments,
+                       flags='r')
+
 #------------------------------------------------------------------------ RASTER
-        if self.type == "cell":      
-                    
+        if self.type == "cell":
+
             if md.identification.title is not (None or ''):
-                _title=md.identification.title
+                _title = md.identification.title
                 Module('r.support',
                        map=self.map,
                        title=_title,
                        overwrite=True)
-                
+
             if md.dataquality.lineage is not (None or ''):
-                _history=md.dataquality.lineage
+                _history = md.dataquality.lineage
                 Module('r.support',
-                       map=self.map,#append
-                       history=_history)   
-            
-            _units=''
-            if len(md.identification.distance)>0:
-                _units+= md.identification.distance.pop()
-            if len(md.identification.uom)>0: 
-                _units+=md.identification.uom.pop()
-            if _units!='':
+                       map=self.map,  # append
+                       history=_history)
+
+            _units = ''
+            if len(md.identification.distance) > 0:
+                _units += md.identification.distance.pop()
+            if len(md.identification.uom) > 0:
+                _units += md.identification.uom.pop()
+            if _units != '':
                 Module('r.support',
                        map=self.map,
                        units=_units,
-                       overwrite=True)  
-                
+                       overwrite=True)
+
             if md.identification.keywords is not None or len(md.identification.keywords) > 0:
-                _comments=self.md_grass['description']
-                for k in md.identification.keywords:  
+                _comments = self.md_grass['description']
+                for k in md.identification.keywords:
                     for kw in k["keywords"]:
-                        if kw!='':
-                            _comments+=kw + ', '
-                    if k["thesaurus"]["title"]!='':
-                        _comments+= k["thesaurus"]["title"] +', '
-                    if k["thesaurus"]["date"]!='':
-                         _comments+= k["thesaurus"]["date"]+', '
-                    if k['thesaurus']['datetype']!='':
-                        _comments+= k['thesaurus']['datetype'] +';'
-                        
+                        if kw != '':
+                            _comments += kw + ', '
+                    if k["thesaurus"]["title"] != '':
+                        _comments += k["thesaurus"]["title"] + ', '
+                    if k["thesaurus"]["date"] != '':
+                        _comments += k["thesaurus"]["date"] + ', '
+                    if k['thesaurus']['datetype'] != '':
+                        _comments += k['thesaurus']['datetype'] + ';'
+
                 Module('r.support',
-                           map=self.map,
-                           description=_comments,
-                           overwrite=True)                
-
+                       map=self.map,
+                       description=_comments,
+                       overwrite=True)

Modified: sandbox/krejcmat/src/mdutil.py
===================================================================
--- sandbox/krejcmat/src/mdutil.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/mdutil.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,33 +1,72 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
-import string,os
-from grass.script       import core as grass
+"""
+ at package mdgrass
+ at module  v.info.iso, r.info.iso, g.gui.metadata
+ at brief   Global methods for metadata management
+
+Methods:
+-mdutil::removeNonAscii
+-mdutil::yesNo
+-mdutil::findBetween
+-mdutil::replaceXMLReservedChar
+-mdutil::pathToMapset
+-mdutil::grassProfileValidator
+-mdutil::isnpireValidator
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
+"""
+
+import string
+import os
+from grass.script import core as grass
 import wx
 
-def removeNonAscii(s): 
-        s= filter(lambda x: x in string.printable, s)
-        return s
-    
-def yesNo(parent, question, caption = 'Yes or no?'):
+
+def removeNonAscii(s):
+    '''Removed non ascii char
+    '''
+    s = filter(lambda x: x in string.printable, s)
+    return s
+
+
+def yesNo(parent, question, caption='Yes or no?'):
+
     dlg = wx.MessageDialog(parent, question, caption, wx.YES_NO | wx.ICON_QUESTION)
     result = dlg.ShowModal() == wx.ID_YES
     dlg.Destroy()
-    return result   
- 
-def replaceXMLReservedChar(input):
-    if input:
+    return result
+
+
+def findBetween(s, first, last):
+    try:
+        start = s.index(first) + len(first)
+        end = s.index(last, start)
+        return s[start:end]
+    except:
+        return ""
+
+
+def replaceXMLReservedChar(inp):
+    if inp:
         import re
 
-        input = re.sub('<', '<', input)
-        input = re.sub('>', '>', input)
-        input = re.sub('&', '&', input)
-        input = re.sub('%', '%', input)
-    return input
+        inp = re.sub('<', '<', inp)
+        inp = re.sub('>', '>', inp)
+        inp = re.sub('&', '&', inp)
+        inp = re.sub('%', '%', inp)
+    return inp
 
+
 def pathToMapset():
-    gisenvDict=grass.gisenv()
-    return os.path.join(gisenvDict['GISDBASE'],gisenvDict['LOCATION_NAME'],gisenvDict['MAPSET']  ) 
-     
+    gisenvDict = grass.gisenv()
+    return os.path.join(gisenvDict['GISDBASE'], gisenvDict['LOCATION_NAME'], gisenvDict['MAPSET'])
+
+
 def grassProfileValidator(md):
     '''function for validation GRASS BASIC XML-OWSLib  file-object'''
 
@@ -37,7 +76,7 @@
     result["num_of_errors"] = "0"
     errors = 0
 
-    if md.identification is None :
+    if md.identification is None:
         result["errors"].append("gmd:CI_ResponsibleParty: Organization missing")
         result["errors"].append("gmd:CI_ResponsibleParty: E-mail missing")
         result["errors"].append("gmd:CI_ResponsibleParty: Role missing")
@@ -57,7 +96,6 @@
             result["errors"].append("gmd:CI_ResponsibleParty: Role missing")
             errors += 3
         else:
-
                 if md.identification.contact[0].organization is (None or ''):
                     result["errors"].append("gmd:CI_ResponsibleParty: Organization missing")
                     errors += 1
@@ -69,7 +107,6 @@
                 if md.identification.contact[0].role is (None or ''):
                     result["errors"].append("gmd:CI_ResponsibleParty: Role missing")
                     errors += 1
-                    
 
         if md.identification.title is (None or ''):
             result["errors"].append("gmd:md_DataIdentification: Title is missing")
@@ -81,11 +118,11 @@
             result["errors"].append("gmd:md_ScopeCode: Resource Type is missing")
             errors += 1
 
-        if md.identification.extent is None :
+        if md.identification.extent is None:
             result["errors"].append("gmd:EX_Extent: extent element is missing")
             errors += 4
         else:
-            if md.identification.extent.boundingBox is None :
+            if md.identification.extent.boundingBox is None:
                 result["errors"].append("gmd:EX_GeographicBoundingBox: bbox is missing")
                 errors += 4
             else:
@@ -110,7 +147,7 @@
     if md.datestamp is (None or ''):
         result["errors"].append("gmd:dateStamp: Date is missing")
         errors += 1
-        
+
     if md.identifier is (None or ''):
         result["errors"].append("gmd:identifier: Identifier is missing")
         errors += 1
@@ -121,7 +158,6 @@
         result["errors"].append("gmd:role: role is missing")
         errors += 3
     else:
-
             if md.contact[0].organization is (None or ''):
                 result["errors"].append("gmd:contact: Organization name is missing")
                 errors += 1
@@ -133,8 +169,7 @@
             if md.contact[0].role is (None or ''):
                 result["errors"].append("gmd:role: role is missing")
                 errors += 1
-                
-                
+
     if errors > 0:
         result["status"] = "failed"
         result["num_of_errors"] = str(errors)
@@ -172,13 +207,13 @@
         result["errors"].append("gmd:otherConstraints is missing")
         errors += 20
     else:
-        if md.identification.contact is None  or len(md.identification.contact) < 1:
+        if md.identification.contact is None or len(md.identification.contact) < 1:
             result["errors"].append("gmd:CI_ResponsibleParty: Organization missing")
             result["errors"].append("gmd:CI_ResponsibleParty: E-mail missing")
             result["errors"].append("gmd:CI_ResponsibleParty: Role missing")
             errors += 3
         else:
- 
+
                 if md.identification.contact[0].organization is (None or ''):
                     result["errors"].append("gmd:CI_ResponsibleParty: Organization missing")
                     errors += 1
@@ -200,28 +235,27 @@
         if md.identification.identtype is (None or ''):
             result["errors"].append("gmd:md_ScopeCode: Resource Type is missing")
             errors += 1
-            
-        if md.identification.resourcelanguage is None :
+
+        if md.identification.resourcelanguage is None:
             errors += 1
             result["errors"].append("gmd:language: Resource Language is missing")
         else:
             if len(md.identification.resourcelanguage) < 1 or md.identification.resourcelanguage[0] == '':
                     result["errors"].append("gmd:language: Resource Language is missing")
                     errors += 1
-                
-                    
+
         if md.identification.uricode is None:
             result["errors"].append("gmd:RS_Identifier: Unique Resource Identifier is missing")
-            errors += 1                           
+            errors += 1
         else:
             if len(md.identification.uricode) < 1 or md.identification.uricode[0] == '':
                 result["errors"].append("gmd:RS_Identifier: Unique Resource Identifier is missing")
                 errors += 1
-                
+
         if md.identification.topiccategory is None:
             result["errors"].append("gmd:topicCategory: TopicCategory is missing")
-            errors += 1  
-        else: 
+            errors += 1
+        else:
             if len(md.identification.topiccategory) < 1 or md.identification.topiccategory[0] == '':
                 result["errors"].append("gmd:topicCategory: TopicCategory is missing")
                 errors += 1
@@ -234,7 +268,7 @@
                 errors += 4
         else:
                 if md.identification.keywords[0]['keywords'] is None or len(md.identification.keywords[0]['keywords']) < 1 \
-                                or str(md.identification.keywords[0]['keywords']) =="[u'']":
+                        or str(md.identification.keywords[0]['keywords']) == "[u'']":
                     result["errors"].append("gmd:MD_Keywords: Keywords are missing")
                     errors += 1
                 if md.identification.keywords[0]['thesaurus'] is None:
@@ -244,23 +278,23 @@
                     errors += 3
                 else:
                     if md.identification.keywords[0]['thesaurus']['title'] is None \
-                            or len(md.identification.keywords[0]['thesaurus']['title'])<1:
+                            or len(md.identification.keywords[0]['thesaurus']['title']) < 1:
                         result["errors"].append("gmd:thesaurusName: Thesaurus Title is missing")
                         errors += 1
                     if md.identification.keywords[0]['thesaurus']['date'] is None \
-                            or len(md.identification.keywords[0]['thesaurus']['date'])<1:
+                            or len(md.identification.keywords[0]['thesaurus']['date']) < 1:
                         result["errors"].append("gmd:thesaurusName: Thesaurus Date is missing")
                         errors += 1
                     if md.identification.keywords[0]['thesaurus']['datetype'] is None \
-                            or len(md.identification.keywords[0]['thesaurus']['datetype'])<1:
+                            or len(md.identification.keywords[0]['thesaurus']['datetype']) < 1:
                         result["errors"].append("gmd:thesaurusName: Thesaurus Date Type is missing")
                         errors += 1
-                    
-        if md.identification.extent is None :
+
+        if md.identification.extent is None:
             result["errors"].append("gmd:EX_Extent: extent element is missing")
             errors += 1
         else:
-            if md.identification.extent.boundingBox is None :
+            if md.identification.extent.boundingBox is None:
                 result["errors"].append(
                     "gmd:EX_GeographicBoundingBox: bbox is missing")
                 errors += 1
@@ -277,13 +311,12 @@
                 if md.identification.extent.boundingBox.maxy is (None or ''):
                     result["errors"].append("gmd:northBoundLatitude: maxy is missing")
                     errors += 1
-                    
-                    
+
         if len(md.identification.date) < 1 or (md.identification.temporalextent_start is (
                 None or '') or md.identification.temporalextent_end is (None or '')):
             result["errors"].append("Both gmd:EX_TemporalExtent and gmd:CI_Date are missing")
             errors += 1
-        
+
         if len(md.identification.uselimitation) < 1 or md.identification.uselimitation[0] == '':
             result["errors"].append("gmd:useLimitation is missing")
             errors += 1
@@ -311,7 +344,7 @@
         result["errors"].append("gmd:DQ_ConformanceResult: title is missing")
         errors += 4
     else:
-        
+
         if md.dataquality.lineage is (None or ''):
             result["errors"].append("gmd:LI_Lineage is missing")
             errors += 1
@@ -328,7 +361,7 @@
             result["errors"].append("gmd:DQ_ConformanceResult: title is missing")
             errors += 1
 
-    if md.contact is None or len( md.contact)<1 :
+    if md.contact is None or len(md.contact) < 1:
         result["errors"].append("gmd:contact: Organization name is missing")
         result["errors"].append("gmd:contact: e-mail is missing")
         result["errors"].append("gmd:role: role is missing")

Modified: sandbox/krejcmat/src/r.info.iso.py
===================================================================
--- sandbox/krejcmat/src/r.info.iso.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/r.info.iso.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,17 +1,14 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
 """
-MODULE:    r.info.iso
+ at module  r.info.iso
+ at brief   Module for creating metadata based on ISO from raster maps
 
-AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
 
-PURPOSE:   Module for creating metadata based on ISO
-
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
-
-           This program is free software under the GNU General Public
-           License (>=v2). Read the file COPYING that comes with GRASS
-           for details.
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
 #%option G_OPT_R_MAP
 #% key: map
@@ -19,10 +16,15 @@
 #% required: yes
 #%end
 
+#%flag
+#% key: o
+#% label: Allow to overwrite exist metadata
+#%end
+
 #%option
 #% key: profil
 #% label: Metadata profil based on ISO
-#% description: INSPIRE schema is not filled properly (unknown values are filled '$NULL')
+#% description: INSPIRE profile is not filled properly (unknown values are filled '$NULL')
 #% options: basic, inspire
 #% answer: basic
 #%end
@@ -44,7 +46,6 @@
 
 
 def main():
-
     if not options['destination']:
         destination = None
     else:
@@ -54,18 +55,26 @@
         mdout = None
     else:
         mdout = options['mdout']
-    print options['map']
+
     md = GrassMD(options['map'], 'cell')
     if options['profil'] == 'inspire':
         md.createGrassInspireISO()
-        xml_file = md.saveXML(destination, mdout)
-        md.readXML(xml_file)
-        print md.validate_inspire()
+        xml_file = md.saveXML(path=destination,
+                              xml_out_name=mdout,
+                              overwrite=flags['o'])
+        if xml_file is not False:
+            md.readXML(xml_file)
+            print md.validate_inspire()
+
     else:
         md.createGrassBasicISO()
-        md.saveXML(destination, mdout)
+        xml_file = md.saveXML(path=destination,
+                              xml_out_name=mdout,
+                              overwrite=flags['o'])
+        if xml_file is not False:
+            md.readXML(xml_file)
+            print md.validate_basic()
 
-
 if __name__ == "__main__":
     options, flags = parser()
     main()

Copied: sandbox/krejcmat/src/templates/basicTemplate.xml (from rev 61573, sandbox/krejcmat/src/templates/grassGRASSTemplateFinal.xml)
===================================================================
--- sandbox/krejcmat/src/templates/basicTemplate.xml	                        (rev 0)
+++ sandbox/krejcmat/src/templates/basicTemplate.xml	2014-08-11 05:43:51 UTC (rev 61579)
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <gmd:fileIdentifier>
+        <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "CharacterString", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
+    </gmd:fileIdentifier>
+    <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "MD_ScopeCode", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
+    </gmd:hierarchyLevel>
+  {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
+    <gmd:contact>
+        <gmd:CI_ResponsibleParty>
+            <gmd:organisationName>
+                <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  inboxmulti = 1,multi = 0,type = "string",group = "Metadata",object="CI_ResponsibleParty()", inbox="Metadata point of contact",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
+            </gmd:organisationName>
+            <gmd:contactInfo>
+                <gmd:CI_Contact>
+                    <gmd:address>
+                        <gmd:CI_Address>
+                            <gmd:electronicMailAddress>
+                                <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1",  multi = 0,object="CI_ResponsibleParty()", inboxmulti = 1,group = "Metadata", inbox="Metadata point of contact",type = "email",example="image2000 at jrc.it", desc="Party responsible for the metadata information." #}</gco:CharacterString>
+                            </gmd:electronicMailAddress>
+                        </gmd:CI_Address>
+                    </gmd:address>
+                </gmd:CI_Contact>
+            </gmd:contactInfo>
+            <gmd:role>
+                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+            </gmd:role>
+        </gmd:CI_ResponsibleParty>
+    </gmd:contact>
+  {% endfor -%}
+    <gmd:dateStamp>
+        <gco:Date>{{ md.datestamp }}{# tag="md.datestamp" , name="Metadata date" , ref= "Part B 10.2" , desc= "Date that the metadata was created.",type = "date" , example = "2005-03-27" , multi= 0 , group= "Metadata" , multiline= False #}</gco:Date>
+    </gmd:dateStamp>
+    <gmd:metadataStandardName>
+        <gco:CharacterString>ISO 19115</gco:CharacterString>
+    </gmd:metadataStandardName>
+    <gmd:metadataStandardVersion>
+        <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
+    </gmd:metadataStandardVersion>
+    <gmd:identificationInfo>
+        <gmd:MD_DataIdentification>
+            <gmd:citation>
+                <gmd:CI_Citation>
+                    <gmd:title>
+                        <gco:CharacterString>{{ md.identification.title }}{# tag="md.identification.title", ref="Part B 1.1", name ="Resource title", desc ="Name by which the cited resource is known.", example ="Image2000 Product 1 (nl2) MultispectB 10.1" , multi = 0, group ="Identification", type = "string", multiline=True #}</gco:CharacterString>
+                    </gmd:title>
+          {% for d in md.identification.date -%}{# tag="for d in md.identification.date" ,name="",object="CI_Date()",group= "Temporal" , inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False #}
+                    <gmd:date>
+                        <gmd:CI_Date>
+                            <gmd:date>
+                                <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",type = "date",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
+                            </gmd:date>
+                            <gmd:dateType>
+                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="{{ d.type }}{# tag="d.type" , group= "Temporal" ,type = "CI_DateTypeCode",object="CI_Date()", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
+                            </gmd:dateType>
+                        </gmd:CI_Date>
+                    </gmd:date>
+                </gmd:CI_Citation>
+            </gmd:citation>
+      {% endfor -%}
+            <gmd:abstract>
+                <gco:CharacterString>{{ md.identification.abstract }}{# tag="md.identification.abstract ",ref="Part B 1.2",  name ="Resource Abstract", desc ="Brief narrative summary of the content of the resource(s).", example ="IMAGE2000 product 1 individual orthorectified scenes. IMAGE2000 was produced from ETM+ Landsat 7 satellite data and provides a consistent European coverage of individual orthorectified scenes in national map projection systems. The year 2000 was targeted as reference year, but a deviation of maximum 1-year was allowed to obtain a full coverage of Europe, which involves approximately 450 Landsat TM Frames. Where Landsat 7 data were not available, Landsat 5 data have been used instead. The spatial resolution is 25 metres for multispectral and 12.5 metres for panchromatic imagery", type = "string", multi = 0, group = "Identification", multiline=True #}</gco:CharacterString>
+            </gmd:abstract>
+      {% for co in md.identification.contact -%}{# tag="for co in md.identification.contact",object="CI_ResponsibleParty()", inboxmulti=1, group = "Responsible party",inbox="Point of contact" #}
+            <gmd:pointOfContact>
+                <gmd:CI_ResponsibleParty>
+                    <gmd:organisationName>
+                        <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  multi = 0, group = "Responsible party",inboxmulti=1 ,inbox="Point of contact",object="CI_ResponsibleParty()",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",type = "string",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
+                    </gmd:organisationName>
+                    <gmd:contactInfo>
+                        <gmd:CI_Contact>
+                            <gmd:address>
+                                <gmd:CI_Address>
+                                    <gmd:electronicMailAddress>
+                                        <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1" , group = "Metadata",inboxmulti=1, inbox="Responsible party",multi=0,type ="email",example="image2000 at jrc.it",object="CI_ResponsibleParty()", desc="Party responsible for the metadata information." #}</gco:CharacterString>
+                                    </gmd:electronicMailAddress>
+                                </gmd:CI_Address>
+                            </gmd:address>
+                        </gmd:CI_Contact>
+                    </gmd:contactInfo>
+                    <gmd:role>
+                        <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",inboxmulti=1,name="Responsible party role",object="CI_ResponsibleParty()",ref="Part B 9.2", type = "CI_RoleCode", multi = 0, group = "Responsible party", inbox="Responsible party",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+                    </gmd:role>
+                </gmd:CI_ResponsibleParty>
+            </gmd:pointOfContact>
+      {% endfor -%}
+      {% for (u,d) in zip( md.identification.uom,md.identification.distance) -%}{# tag="for (d,u) in zip(md.identification.distance, md.identification.uom)", group = "Quality and Validity", inbox="Spatial resolution-distance",inboxmulti= 1 #}
+                     <gmd:spatialResolution>
+                        <gmd:MD_Resolution>
+                            <gmd:distance>
+                                <gco:Distance uom="{{ u }}{# tag="u" , name="Units" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "m" , type ="string" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}"
+>{{ d }}{# tag="d" , name="Resolution" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "25" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}</gco:Distance>
+                            </gmd:distance>
+                        </gmd:MD_Resolution>
+                    </gmd:spatialResolution>
+      {% endfor -%}
+            <gmd:extent>
+                <gmd:EX_Extent>
+                    <gmd:geographicElement>
+                        <gmd:EX_GeographicBoundingBox>
+                            <gmd:westBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.minx }}{# tag="md.identification.extent.boundingBox.minx" , name="West Bound Longitude" , ref= "Part B 4.1" , desc= "Western-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "3.93" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:westBoundLongitude>
+                            <gmd:eastBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxx }}{# tag="md.identification.extent.boundingBox.maxx" , name="East Bound Longitude" , ref= "Part B 4.1" , desc= "Eastern-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "7.57" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:eastBoundLongitude>
+                            <gmd:southBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.miny }}{# tag="md.identification.extent.boundingBox.miny" , name="South Bound Latitude" , ref= "Part B 4.1" , desc= "Southern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "52.10" , type ="decimal" , group= "Geographic" ,multi=0 , multiline= False #}</gco:Decimal>
+                            </gmd:southBoundLatitude>
+                            <gmd:northBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxy }}{# tag="md.identification.extent.boundingBox.maxy" , name="North Bound Latitude" , ref= "Part B 4.1" , desc= "Northern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "54.10" , type ="decimal" , group= "Geographic" , multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:northBoundLatitude>
+                        </gmd:EX_GeographicBoundingBox>
+                    </gmd:geographicElement>
+                </gmd:EX_Extent>
+            </gmd:extent>
+            </gmd:MD_DataIdentification>
+            </gmd:identificationInfo>
+            <gmd:distributionInfo>
+                <gmd:MD_Distribution>
+                    <gmd:distributionFormat>
+                        <gmd:MD_Format>
+                            <gmd:name gco:nilReason="inapplicable"/>
+                            <gmd:version gco:nilReason="inapplicable"/>
+                        </gmd:MD_Format>
+                    </gmd:distributionFormat>
+                </gmd:MD_Distribution>
+            </gmd:distributionInfo>
+    <gmd:dataQualityInfo>
+        <gmd:DQ_DataQuality>
+      <gmd:lineage>
+        <gmd:LI_Lineage>
+          <gmd:statement>
+            <gco:CharacterString>{{ md.dataquality.lineage }}{# tag="md.dataquality.lineage" , name="Lineage" , ref= "Part B 6.1" , desc= "General explanation of the data producers knowledge about the lineage of a dataset." , example = "Product 1 scenes correspond to the path/row of the Landsat orbit.." , type ="string" , group= "Quality and Validity" ,  multiline= True #}</gco:CharacterString>
+          </gmd:statement>
+        </gmd:LI_Lineage>
+      </gmd:lineage>
+    </gmd:DQ_DataQuality>
+  </gmd:dataQualityInfo>
+        </gmd:MD_Metadata>

Deleted: sandbox/krejcmat/src/templates/grassGRASSTemplateFinal.xml
===================================================================
--- sandbox/krejcmat/src/templates/grassGRASSTemplateFinal.xml	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/templates/grassGRASSTemplateFinal.xml	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,141 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <gmd:fileIdentifier>
-        <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "CharacterString", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
-    </gmd:fileIdentifier>
-    <gmd:hierarchyLevel>
-        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "MD_ScopeCode", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
-    </gmd:hierarchyLevel>
-  {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
-    <gmd:contact>
-        <gmd:CI_ResponsibleParty>
-            <gmd:organisationName>
-                <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  inboxmulti = 1,multi = 0,type = "string",group = "Metadata",object="CI_ResponsibleParty()", inbox="Metadata point of contact",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
-            </gmd:organisationName>
-            <gmd:contactInfo>
-                <gmd:CI_Contact>
-                    <gmd:address>
-                        <gmd:CI_Address>
-                            <gmd:electronicMailAddress>
-                                <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1",  multi = 0,object="CI_ResponsibleParty()", inboxmulti = 1,group = "Metadata", inbox="Metadata point of contact",type = "email",example="image2000 at jrc.it", desc="Party responsible for the metadata information." #}</gco:CharacterString>
-                            </gmd:electronicMailAddress>
-                        </gmd:CI_Address>
-                    </gmd:address>
-                </gmd:CI_Contact>
-            </gmd:contactInfo>
-            <gmd:role>
-                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
-            </gmd:role>
-        </gmd:CI_ResponsibleParty>
-    </gmd:contact>
-  {% endfor -%}
-    <gmd:dateStamp>
-        <gco:Date>{{ md.datestamp }}{# tag="md.datestamp" , name="Metadata date" , ref= "Part B 10.2" , desc= "Date that the metadata was created.",type = "date" , example = "2005-03-27" , multi= 0 , group= "Metadata" , multiline= False #}</gco:Date>
-    </gmd:dateStamp>
-    <gmd:metadataStandardName>
-        <gco:CharacterString>ISO 19115</gco:CharacterString>
-    </gmd:metadataStandardName>
-    <gmd:metadataStandardVersion>
-        <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
-    </gmd:metadataStandardVersion>
-    <gmd:identificationInfo>
-        <gmd:MD_DataIdentification>
-            <gmd:citation>
-                <gmd:CI_Citation>
-                    <gmd:title>
-                        <gco:CharacterString>{{ md.identification.title }}{# tag="md.identification.title", ref="Part B 1.1", name ="Resource title", desc ="Name by which the cited resource is known.", example ="Image2000 Product 1 (nl2) MultispectB 10.1" , multi = 0, group ="Identification", type = "string", multiline=True #}</gco:CharacterString>
-                    </gmd:title>
-          {% for d in md.identification.date -%}{# tag="for d in md.identification.date" ,name="",object="CI_Date()",group= "Temporal" , inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False #}
-                    <gmd:date>
-                        <gmd:CI_Date>
-                            <gmd:date>
-                                <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",type = "date",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
-                            </gmd:date>
-                            <gmd:dateType>
-                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue="{{ d.type }}{# tag="d.type" , group= "Temporal" ,type = "CI_DateTypeCode",object="CI_Date()", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
-                            </gmd:dateType>
-                        </gmd:CI_Date>
-                    </gmd:date>
-                </gmd:CI_Citation>
-            </gmd:citation>
-      {% endfor -%}
-            <gmd:abstract>
-                <gco:CharacterString>{{ md.identification.abstract }}{# tag="md.identification.abstract ",ref="Part B 1.2",  name ="Resource Abstract", desc ="Brief narrative summary of the content of the resource(s).", example ="IMAGE2000 product 1 individual orthorectified scenes. IMAGE2000 was produced from ETM+ Landsat 7 satellite data and provides a consistent European coverage of individual orthorectified scenes in national map projection systems. The year 2000 was targeted as reference year, but a deviation of maximum 1-year was allowed to obtain a full coverage of Europe, which involves approximately 450 Landsat TM Frames. Where Landsat 7 data were not available, Landsat 5 data have been used instead. The spatial resolution is 25 metres for multispectral and 12.5 metres for panchromatic imagery", type = "string", multi = 0, group = "Identification", multiline=True #}</gco:CharacterString>
-            </gmd:abstract>
-      {% for co in md.identification.contact -%}{# tag="for co in md.identification.contact",object="CI_ResponsibleParty()", inboxmulti=1, group = "Responsible party",inbox="Point of contact" #}
-            <gmd:pointOfContact>
-                <gmd:CI_ResponsibleParty>
-                    <gmd:organisationName>
-                        <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  multi = 0, group = "Responsible party",inboxmulti=1 ,inbox="Point of contact",object="CI_ResponsibleParty()",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",type = "string",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
-                    </gmd:organisationName>
-                    <gmd:contactInfo>
-                        <gmd:CI_Contact>
-                            <gmd:address>
-                                <gmd:CI_Address>
-                                    <gmd:electronicMailAddress>
-                                        <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1" , group = "Metadata",inboxmulti=1, inbox="Responsible party",multi=0,type ="email",example="image2000 at jrc.it",object="CI_ResponsibleParty()", desc="Party responsible for the metadata information." #}</gco:CharacterString>
-                                    </gmd:electronicMailAddress>
-                                </gmd:CI_Address>
-                            </gmd:address>
-                        </gmd:CI_Contact>
-                    </gmd:contactInfo>
-                    <gmd:role>
-                        <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",inboxmulti=1,name="Responsible party role",object="CI_ResponsibleParty()",ref="Part B 9.2", type = "CI_RoleCode", multi = 0, group = "Responsible party", inbox="Responsible party",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
-                    </gmd:role>
-                </gmd:CI_ResponsibleParty>
-            </gmd:pointOfContact>
-      {% endfor -%}
-      {% for (u,d) in zip( md.identification.uom,md.identification.distance) -%}{# tag="for (d,u) in zip(md.identification.distance, md.identification.uom)", group = "Quality and Validity", inbox="Spatial resolution-distance",inboxmulti= 1 #}
-                     <gmd:spatialResolution>
-                        <gmd:MD_Resolution>
-                            <gmd:distance>
-                                <gco:Distance uom="{{ u }}{# tag="u" , name="Units" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "m" , type ="string" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}"
->{{ d }}{# tag="d" , name="Resolution" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "25" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}</gco:Distance>
-                            </gmd:distance>
-                        </gmd:MD_Resolution>
-                    </gmd:spatialResolution>
-      {% endfor -%}
-            <gmd:extent>
-                <gmd:EX_Extent>
-                    <gmd:geographicElement>
-                        <gmd:EX_GeographicBoundingBox>
-                            <gmd:westBoundLongitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.minx }}{# tag="md.identification.extent.boundingBox.minx" , name="West Bound Longitude" , ref= "Part B 4.1" , desc= "Western-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "3.93" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:westBoundLongitude>
-                            <gmd:eastBoundLongitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxx }}{# tag="md.identification.extent.boundingBox.maxx" , name="East Bound Longitude" , ref= "Part B 4.1" , desc= "Eastern-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "7.57" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:eastBoundLongitude>
-                            <gmd:southBoundLatitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.miny }}{# tag="md.identification.extent.boundingBox.miny" , name="South Bound Latitude" , ref= "Part B 4.1" , desc= "Southern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "52.10" , type ="decimal" , group= "Geographic" ,multi=0 , multiline= False #}</gco:Decimal>
-                            </gmd:southBoundLatitude>
-                            <gmd:northBoundLatitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxy }}{# tag="md.identification.extent.boundingBox.maxy" , name="North Bound Latitude" , ref= "Part B 4.1" , desc= "Northern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "54.10" , type ="decimal" , group= "Geographic" , multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:northBoundLatitude>
-                        </gmd:EX_GeographicBoundingBox>
-                    </gmd:geographicElement>
-                </gmd:EX_Extent>
-            </gmd:extent>
-            </gmd:MD_DataIdentification>
-            </gmd:identificationInfo>
-            <gmd:distributionInfo>
-                <gmd:MD_Distribution>
-                    <gmd:distributionFormat>
-                        <gmd:MD_Format>
-                            <gmd:name gco:nilReason="inapplicable"/>
-                            <gmd:version gco:nilReason="inapplicable"/>
-                        </gmd:MD_Format>
-                    </gmd:distributionFormat>
-                </gmd:MD_Distribution>
-            </gmd:distributionInfo>
-    <gmd:dataQualityInfo>
-        <gmd:DQ_DataQuality>
-      <gmd:lineage>
-        <gmd:LI_Lineage>
-          <gmd:statement>
-            <gco:CharacterString>{{ md.dataquality.lineage }}{# tag="md.dataquality.lineage" , name="Lineage" , ref= "Part B 6.1" , desc= "General explanation of the data producers knowledge about the lineage of a dataset." , example = "Product 1 scenes correspond to the path/row of the Landsat orbit.." , type ="string" , group= "Quality and Validity" ,  multiline= True #}</gco:CharacterString>
-          </gmd:statement>
-        </gmd:LI_Lineage>
-      </gmd:lineage>
-    </gmd:DQ_DataQuality>
-  </gmd:dataQualityInfo>
-        </gmd:MD_Metadata>

Deleted: sandbox/krejcmat/src/templates/grassInspireTemplateFinal.xml
===================================================================
--- sandbox/krejcmat/src/templates/grassInspireTemplateFinal.xml	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/templates/grassInspireTemplateFinal.xml	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,317 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd"
-    xmlns:gmd="http://www.isotc211.org/2005/gmd"
-    xmlns:gco="http://www.isotc211.org/2005/gco"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns:gml="http://www.opengis.net/gml"
-    xmlns:xlink="http://www.w3.org/1999/xlink">
-    <gmd:fileIdentifier>
-        <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "string", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
-    </gmd:fileIdentifier>
-    <gmd:language>
-        <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ md.languagecode }}{# tag="md.languagecode", name ="Metadata language", desc ="Language(s) used within the datasets", example ="eng", type = "string", multi = 0, group = "Metadata",multiline=False #}">{{ md.languagecode }}</gmd:LanguageCode>
-    </gmd:language>
-    <gmd:hierarchyLevel>
-        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
-    </gmd:hierarchyLevel>
-  {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
-    <gmd:contact>
-        <gmd:CI_ResponsibleParty>
-            <gmd:organisationName>
-                <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  inboxmulti = 1,multi = 0,type = "string",group = "Metadata",object="CI_ResponsibleParty()", inbox="Metadata point of contact",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
-            </gmd:organisationName>
-            <gmd:contactInfo>
-                <gmd:CI_Contact>
-                    <gmd:address>
-                        <gmd:CI_Address>
-                            <gmd:electronicMailAddress>
-                                <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1",  multi = 0,object="CI_ResponsibleParty()", inboxmulti = 1,group = "Metadata", inbox="Metadata point of contact",type = "email",example="image2000 at jrc.it", desc="Party responsible for the metadata information." #}</gco:CharacterString>
-                            </gmd:electronicMailAddress>
-                        </gmd:CI_Address>
-                    </gmd:address>
-                </gmd:CI_Contact>
-            </gmd:contactInfo>
-            <gmd:role>
-                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
-            </gmd:role>
-        </gmd:CI_ResponsibleParty>
-    </gmd:contact>
-  {% endfor -%}
-    <gmd:dateStamp>
-        <gco:Date>{{ md.datestamp }}{# tag="md.datestamp" , name="Metadata date" , ref= "Part B 10.2" , desc= "Date that the metadata was created." , example = "2005-03-27" , type ="date" , multi= 0 , group= "Metadata" , multiline= False #}</gco:Date>
-    </gmd:dateStamp>
-    <gmd:metadataStandardName>
-        <gco:CharacterString>ISO 19115</gco:CharacterString>
-    </gmd:metadataStandardName>
-    <gmd:metadataStandardVersion>
-        <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
-    </gmd:metadataStandardVersion>
-    <gmd:identificationInfo>
-        <gmd:MD_DataIdentification>
-            <gmd:citation>
-                <gmd:CI_Citation>
-                    <gmd:title>
-                        <gco:CharacterString>{{ md.identification.title }}{# tag="md.identification.title", ref="Part B 1.1", name ="Resource title", desc ="Name by which the cited resource is known.", example ="Image2000 Product 1 (nl2) MultispectB 10.1" , multi = 0, group ="Identification", type = "string", multiline=True #}</gco:CharacterString>
-                    </gmd:title>
-          {% for d in md.identification.date -%}{# tag="for d in md.identification.date" ,name="",object="CI_Date()",group= "Temporal" , inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False #}
-                    <gmd:date>
-                        <gmd:CI_Date>
-                            <gmd:date>
-                                <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()",type = "date", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
-                            </gmd:date>
-                            <gmd:dateType>
-                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ d.type }}{# tag="d.type" , group= "Temporal" ,object="CI_Date()",type = "CI_DateTypeCode", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
-                            </gmd:dateType>
-                        </gmd:CI_Date>
-                    </gmd:date>
-          {% endfor -%}
-{% for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace) -%}{# tag="for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace)", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" #}
-                                     <gmd:identifier>
-                                        <gmd:RS_Identifier>
-                                            <gmd:code>
-                                                <gco:CharacterString>{{ cod }}{# tag="cod", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it # image2000_1_nl2_multi", type = "string", multi = 0  #}</gco:CharacterString>
-                                            </gmd:code>
-                                            <gmd:codeSpace>
-                                                <gco:CharacterString>{{ code }}{# tag="code", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code space", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it", type = "string", multi = 0 #}</gco:CharacterString>
-                                            </gmd:codeSpace>
-                                        </gmd:RS_Identifier>
-                                  </gmd:identifier>
-                      {% endfor -%}
-                </gmd:CI_Citation>
-            </gmd:citation>
-            <gmd:abstract>
-                <gco:CharacterString>{{ md.identification.abstract }}{# tag="md.identification.abstract ",ref="Part B 1.2",  name ="Resource Abstract", desc ="Brief narrative summary of the content of the resource(s).", example ="IMAGE2000 product 1 individual orthorectified scenes. IMAGE2000 was produced from ETM+ Landsat 7 satellite data and provides a consistent European coverage of individual orthorectified scenes in national map projection systems. The year 2000 was targeted as reference year, but a deviation of maximum 1-year was allowed to obtain a full coverage of Europe, which involves approximately 450 Landsat TM Frames. Where Landsat 7 data were not available, Landsat 5 data have been used instead. The spatial resolution is 25 metres for multispectral and 12.5 metres for panchromatic imagery", type = "string", multi = 0, group = "Identification", multiline=True #}</gco:CharacterString>
-            </gmd:abstract>
-      {% for co in md.identification.contact -%}{# tag="for co in md.identification.contact",object="CI_ResponsibleParty()", inboxmulti=1, group = "Responsible party",inbox="Point of contact" #}
-            <gmd:pointOfContact>
-                <gmd:CI_ResponsibleParty>
-                    <gmd:organisationName>
-                        <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1", type = "string", multi = 0, group = "Responsible party",inboxmulti=1 ,inbox="Point of contact",object="CI_ResponsibleParty()",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
-                    </gmd:organisationName>
-                    <gmd:contactInfo>
-                        <gmd:CI_Contact>
-                            <gmd:address>
-                                <gmd:CI_Address>
-                                    <gmd:electronicMailAddress>
-                                        <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1" , group = "Metadata",inboxmulti=1, inbox="Responsible party",multi=0,example="image2000 at jrc.it",object="CI_ResponsibleParty()", type = "email",desc="Party responsible for the metadata information." #}</gco:CharacterString>
-                                    </gmd:electronicMailAddress>
-                                </gmd:CI_Address>
-                            </gmd:address>
-                        </gmd:CI_Contact>
-                    </gmd:contactInfo>
-                    <gmd:role>
-                        <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",inboxmulti=1,name="Responsible party role",type = "CI_RoleCode",object="CI_ResponsibleParty()",ref="Part B 9.2",  multi = 0, group = "Responsible party", inbox="Responsible party",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
-                    </gmd:role>
-                </gmd:CI_ResponsibleParty>
-            </gmd:pointOfContact>
-      {% endfor -%}
-{% for k in md.identification.keywords -%}{# tag="for k in md.identification.keywords" ,group = "Keywords",inbox="Free keywords",inboxmulti=1 #}
-            <gmd:descriptiveKeywords>
-                <gmd:MD_Keywords>
-          {% for kw in k["keywords"] -%}{# tag='for kw in k["keywords"]',group = "Keywords",inbox="Free keywords",inboxmulti=1 #}
-                    
-                    <gmd:keyword>
-                        <gco:CharacterString>{{ kw }}{# tag="kw",ref="Part B 3.1", name ="Keyword",example="Land cover (INSPIRE Spatial Data Theme),humanCatalogueViewer (spatial data service,subcategory), water springs (AGROVOC), freshwater (GEMET Concepts)", desc ="Commonly used word(s) or formalised word(s) or phrase(s) used to describe the subject." , type = "string",inboxmulti=1, multi = 1, group = "Keywords", multiline=False, inbox="Free keywords" #} </gco:CharacterString>
-                    </gmd:keyword>
-          {% endfor -%}
-                    <gmd:thesaurusName>
-                        <gmd:CI_Citation>
-                            <gmd:title>
-                                <gco:CharacterString>{{ k["thesaurus"]["title"] }}{# tag='k["thesaurus"]["title"]', name ="Title", desc ="This citation shall include title of keywords )" , type = "string", multi = 0,inboxmulti=1, group = "Keywords", multiline=False, inbox="Free keywords" #}</gco:CharacterString>
-                            </gmd:title>
-                            <gmd:date>
-                                <gmd:CI_Date>
-                                    <gmd:date>
-                                        <gco:Date>{{ k["thesaurus"]["date"] }}{# tag='k["thesaurus"]["date"]', name ="Reference date", desc ="This citation shall include at least the title a reference date(publication, revision, creation." , type = "date",inboxmulti=1, multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" #}</gco:Date>
-                                    </gmd:date>
-                                    <gmd:dateType>
-                                        <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ k["thesaurus"]["datetype"] }}{{ k["thesaurus"]["datetype"] }}{# tag='k["thesaurus"]["datetype"]', type = "CI_DateTypeCode",name ="Date type",inboxmulti=1, desc ="Options Date of creation, Date of last revision, date of publication" , multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" #}" >{{ k["thesaurus"]["datetype"] }}</gmd:CI_DateTypeCode>
-                                    </gmd:dateType>
-                                </gmd:CI_Date>
-                            </gmd:date>
-                        </gmd:CI_Citation>
-                    </gmd:thesaurusName>
-                </gmd:MD_Keywords>
-            </gmd:descriptiveKeywords>
-      {% endfor -%}
-      {% for rc in md.identification.uselimitation -%}{# tag="for rc in md.identification.uselimitation" , group= "Constraints" ,inbox="Condition applying to access and use", inboxmulti=1 #}
-            <gmd:resourceConstraints>
-                <gmd:MD_Constraints>
-                    <gmd:useLimitation>
-                        <gco:CharacterString>{{ rc }}{# tag="rc" , name="Use limitation" , ref= "Part B 8.1" , desc= "restrictions on the access and use of a resource or metadata" , example = "no conditions apply" , type ="string" ,group= "Constraints" , multi= 0, multiline= False,inbox="Condition applying to access and use", inboxmulti=1  #}</gco:CharacterString>
-                    </gmd:useLimitation>
-                </gmd:MD_Constraints>
-            </gmd:resourceConstraints>
-      {% endfor -%}
-      {% for oc in md.identification.accessconstraints -%}{# tag="for oc in md.identification.otherconstraints" , group= "Constraints",inbox="Other restriction", inboxmulti=1  #}
-            <gmd:resourceConstraints>
-                <gmd:MD_LegalConstraints>
-                    <gmd:accessConstraints>
-                        <gmd:MD_RestrictionCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#MD_RestrictionCode" codeListValue="{{ oc }}{# tag="oc" , name="Other constraionts" , ref= "Part B 8.1" , desc= "Restrictions on the access and use of a resource or metadata" , example = "No conditions apply" , type ="MD_RestrictionCode" ,group= "Constraints" , multi= 0, multiline= False,inbox="Other restriction", inboxmulti=1  #}">{{ oc }}</gmd:MD_RestrictionCode>
-                    </gmd:accessConstraints>
-               {% endfor -%}
-      {% for ac in md.identification.accessconstraints -%}{# tag="for oc in md.identification.accessconstraints" , group= "Constraints",inbox="Limitation on public access", inboxmulti=1  #}
-                    <gmd:otherConstraints>
-                        <gco:CharacterString>{{ ac }} {# tag="ac" ,name="Access constraints", group= "Constraints",inbox="Limitations on public access", inboxmulti=1,ref= "Part B 8.2" , desc= "access constraints applied to assure the protection of privacy or intellectual property, and any special restrictionsor limitations on obtaining the resource." , example = "intellectualPropertyRights (rights to financial benefit from and control of distribution of non tangible property that is a result of creativity)." , type ="string", multi=0 ,  multiline= False #}</gco:CharacterString>
-                    </gmd:otherConstraints>
-                </gmd:MD_LegalConstraints>
-            </gmd:resourceConstraints>
-      {% endfor -%}
-      {% if md.identification.denominators|length > 0 -%}{# tag="if md.identification.denominators|length > 0", group = "Quality and Validity", inbox="Spatial resolution-scale",inboxmulti= 1 #}
-{% for den in md.identification.denominators -%}{# tag="for den in md.identification.denominators", group = "Quality and Validity", inbox="Spatial resolution-scale",inboxmulti= 1 #}
-            <gmd:spatialResolution>
-                <gmd:MD_Resolution>
-                    <gmd:equivalentScale>
-                        <gmd:MD_RepresentativeFraction>
-                            <gmd:denominator>
-                                <gco:Integer>{{ den }}{# tag="den" , name="Equivalent scale" , ref= "Part B 6.2" , desc= "level of detail expressed as the scale denominator of a comparable hardcopy map or chart" , example = "50000 (e.g. 1:50000 scale map)" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-scale", multi=0 , inboxmulti=1, multiline= False #}</gco:Integer>
-                            </gmd:denominator>
-                        </gmd:MD_RepresentativeFraction>
-                    </gmd:equivalentScale>
-                </gmd:MD_Resolution>
-            </gmd:spatialResolution>
-      {% endfor -%}
-      {% endif -%}
-      {% for (d,u) in zip(md.identification.distance, md.identification.uom) -%}{# tag="for (d,u) in zip(md.identification.distance, md.identification.uom)", group = "Quality and Validity", inbox="Spatial resolution-distance",inboxmulti= 1 #}
-            <gmd:spatialResolution>
-                <gmd:MD_Resolution>
-                    <gmd:distance>
-                        <gco:Distance uom="{{ u }}{# tag="u" , name="Units" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "m" , type ="string" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}">
-{{ d }}{# tag="d" , name="Resolution" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "25" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}</gco:Distance>
-                    </gmd:distance>
-                </gmd:MD_Resolution>
-            </gmd:spatialResolution>
-      {% endfor -%}
-      {% for lan in md.identification.resourcelanguage -%}{# tag="for lan in md.identification.resourcelanguage" , group= "Identification" ,inbox='Languages',inboxmulti=1, multiline= False #}
-            <gmd:language>
-                <gmd:LanguageCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ lan }}{# tag="lan" , name="Metadata language" , ref= "Part B 10.3" , desc= "Language used for documenting metadata." , example = "eng" , type ="LanguageCode (ISO/TS 19139)" ,multi=0,inbox='Languages',inboxmulti=1, group= "Identification" , multiline= False #}">{{ lan }}</gmd:LanguageCode>
-            </gmd:language>
-      {% endfor -%}
-      {% for tc in md.identification.topiccategory -%}{# tag="for tc in md.identification.topiccategory", inbox='Topic category',group= "Classification", multiline= False #}
-            <gmd:topicCategory>
-                <gmd:MD_TopicCategoryCode>{{ tc }}{# tag="tc" , name="Topic" , ref= "Part B 2.1" , desc= "Main theme(s) of the dataset" ,inbox='Topic category', example = "imageryBaseMapsEarthCover" , type ="MD_TopicCategory" , group= "Classification" ,  multi=0 , multiline= False #}</gmd:MD_TopicCategoryCode>
-            </gmd:topicCategory>
-      {% endfor -%}
-            <gmd:extent>
-                <gmd:EX_Extent>
-                    <gmd:geographicElement>
-                        <gmd:EX_GeographicBoundingBox>
-                            <gmd:westBoundLongitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.minx }}{# tag="md.identification.extent.boundingBox.minx" , name="West Bound Longitude" , ref= "Part B 4.1" , desc= "Western-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "3.93" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:westBoundLongitude>
-                            <gmd:eastBoundLongitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxx }}{# tag="md.identification.extent.boundingBox.maxx" , name="East Bound Longitude" , ref= "Part B 4.1" , desc= "Eastern-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "7.57" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:eastBoundLongitude>
-                            <gmd:southBoundLatitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.miny }}{# tag="md.identification.extent.boundingBox.miny" , name="South Bound Latitude" , ref= "Part B 4.1" , desc= "Southern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "52.10" , type ="decimal" , group= "Geographic" ,multi=0 , multiline= False #}</gco:Decimal>
-                            </gmd:southBoundLatitude>
-                            <gmd:northBoundLatitude>
-                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxy }}{# tag="md.identification.extent.boundingBox.maxy" , name="North Bound Latitude" , ref= "Part B 4.1" , desc= "Northern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "54.10" , type ="decimal" , group= "Geographic" , multi=0 ,  multiline= False #}</gco:Decimal>
-                            </gmd:northBoundLatitude>
-                        </gmd:EX_GeographicBoundingBox>
-                    </gmd:geographicElement>
-                </gmd:EX_Extent>
-            </gmd:extent>
-      {% if md.identification.temporalextent_start != None -%}{# tag="if md.identification.temporalextent_start != None", group = "Temporal", inbox="Temporal Extent",inboxmulti= 0 #}
-            <gmd:extent>
-                <gmd:EX_Extent>
-                    <gmd:temporalElement>
-                        <gmd:EX_TemporalExtent>
-                            <gmd:extent>
-                                <gml:TimePeriod xsi:type="gml:TimePeriodType">
-                                    <gml:beginPosition>{{ md.identification.temporalextent_start }}{# tag="md.identification.temporalextent_start" , name="Starting date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extend", multi=0 , inboxmulti= 0, multiline= False #}</gml:beginPosition>
-                                    <gml:endPosition>{{ md.identification.temporalextent_end }}{# tag="md.identification.temporalextent_end" , name="Ending date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extend", multi=0 , inboxmulti= 0, multiline= False #}</gml:endPosition>
-                                </gml:TimePeriod>
-                            </gmd:extent>
-                        </gmd:EX_TemporalExtent>
-                    </gmd:temporalElement>
-                </gmd:EX_Extent>
-            </gmd:extent>
-      {% endif -%}
-        </gmd:MD_DataIdentification>
-    </gmd:identificationInfo>
-    <gmd:distributionInfo>
-        <gmd:MD_Distribution>
-            <gmd:distributionFormat>
-                <gmd:MD_Format>
-                    <gmd:name gco:nilReason="inapplicable"/>
-                    <gmd:version gco:nilReason="inapplicable"/>
-                </gmd:MD_Format>
-            </gmd:distributionFormat>
-            <gmd:transferOptions>
-                <gmd:MD_DigitalTransferOptions>
-          {% for ln in md.distribution.online -%}{# tag="for ln in md.distribution.online" , group= "Identification",object='CI_OnlineResource()'  #}
-                    <gmd:onLine>
-                        <gmd:CI_OnlineResource>
-                            <gmd:linkage>
-                                <gmd:URL>{{ ln.url }}{# tag="ln.url" , name="Linkage" , ref= "Part B 1.4" ,object='CI_OnlineResource()', desc= "Location (address) for on-line access using a Uniform Resource Locator address or similar addressing scheme." , example = "http://image2000.jrc.it" , type ="url" , group= "Identification" ,multi=1, multiline= False #}</gmd:URL>
-                            </gmd:linkage>
-                        </gmd:CI_OnlineResource>
-                    </gmd:onLine>
-          {% endfor -%}
-                </gmd:MD_DigitalTransferOptions>
-            </gmd:transferOptions>
-        </gmd:MD_Distribution>
-    </gmd:distributionInfo>
-    <gmd:dataQualityInfo>
-        <gmd:DQ_DataQuality>
-            <gmd:scope>
-                <gmd:DQ_Scope>
-                    <gmd:level>
-                        <gmd:MD_ScopeCode codeListValue="{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Conformity",multiline=False #}" codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode">{{ md.identification.identtype }}</gmd:MD_ScopeCode>
-                    </gmd:level>
-                </gmd:DQ_Scope>
-            </gmd:scope>
- {% for (t,d,dt,dg) in zip(md.dataquality.conformancetitle,md.dataquality.conformancedate,md.dataquality.conformancedatetype,md.dataquality.conformancedegree) -%}{# tag="for (t,d,dt,dg) in zip(md.dataquality.conformancetitle,md.dataquality.conformancedate,md.dataquality.conformancedatetype,md.dataquality.conformancedegree)", group = "Conformity", inbox="Conformity",inboxmulti= 1 #}
-            <gmd:report>
-                <gmd:DQ_DomainConsistency xsi:type="gmd:DQ_DomainConsistency_Type">
-                    <gmd:measureIdentification>
-                        <gmd:RS_Identifier>
-                            <gmd:code>
-                                <gco:CharacterString>Conformity</gco:CharacterString>
-                            </gmd:code>
-                            <gmd:codeSpace>
-                                <gco:CharacterString>INSPIRE</gco:CharacterString>
-                            </gmd:codeSpace>
-                        </gmd:RS_Identifier>
-                    </gmd:measureIdentification>
-                    <gmd:result>
-                        <gmd:DQ_ConformanceResult xsi:type="gmd:DQ_ConformanceResult_Type">
-                            <gmd:specification>
-                                <gmd:CI_Citation>
-                                    <gmd:title>
-                                        <gco:CharacterString>{{ t }}{# tag="t" , name="Specification" , ref= "Part B 7.1" , desc= "citation of the product specification or user requirement against which data is being evaluated." , example = "INSPIRE Data Specification on orthoimagery - Guidelines" , type ="string" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= True #}</gco:CharacterString>
-                                    </gmd:title>
-                                    <gmd:date>
-                                        <gmd:CI_Date>
-                                            <gmd:date>
-                                                <gco:Date>{{ d }}{# tag="d" , name="Date" , ref= "Part B 7.1" , desc= "citation of the product specification or user requirement against which data is being evaluated." , example = "2010-04-26" , type ="date" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Date>
-                                            </gmd:date>
-                                            <gmd:dateType>
-                                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue={{ "\"%s\"" % dt }}>{{ dt }}{# tag="dt" , name="Date type" , ref= "Part B 7.1" , desc= "a date type: creation, revision or publication." , example = "publication" , type ="dateType" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gmd:CI_DateTypeCode>
-                                            </gmd:dateType>
-                                        </gmd:CI_Date>
-                                    </gmd:date>
-                                </gmd:CI_Citation>
-                            </gmd:specification>
-                            <gmd:explanation>
-                                <gco:CharacterString>See the referenced specification</gco:CharacterString>
-                            </gmd:explanation>
-                            <gmd:pass>
-                                <gco:Boolean>{{ dg }}{# tag="dg" , name="Degree/Pass" , ref= "Part B 7.2" , desc= "indication of the conformance result" , example = "True." , type ="boolean" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Boolean>
-                            </gmd:pass>
-                        </gmd:DQ_ConformanceResult>
-                    </gmd:result>
-                </gmd:DQ_DomainConsistency>
-            </gmd:report>
-      {% endfor -%}
-      <gmd:lineage>
-        <gmd:LI_Lineage>
-          <gmd:statement>
-            <gco:CharacterString>{{ md.dataquality.lineage }}{# tag="md.dataquality.lineage" , name="Lineage" , ref= "Part B 6.1" , desc= "General explanation of the data producers knowledge about the lineage of a dataset." , example = "Product 1 scenes correspond to the path/row of the Landsat orbit.." , type ="string" , group= "Quality and Validity" ,  multiline= True #}</gco:CharacterString>
-          </gmd:statement>
-        </gmd:LI_Lineage>
-      </gmd:lineage>
-    </gmd:DQ_DataQuality>
-  </gmd:dataQualityInfo>
-</gmd:MD_Metadata>

Copied: sandbox/krejcmat/src/templates/inspireTemplate.xml (from rev 61573, sandbox/krejcmat/src/templates/grassInspireTemplateFinal.xml)
===================================================================
--- sandbox/krejcmat/src/templates/inspireTemplate.xml	                        (rev 0)
+++ sandbox/krejcmat/src/templates/inspireTemplate.xml	2014-08-11 05:43:51 UTC (rev 61579)
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd"
+    xmlns:gmd="http://www.isotc211.org/2005/gmd"
+    xmlns:gco="http://www.isotc211.org/2005/gco"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:gml="http://www.opengis.net/gml"
+    xmlns:xlink="http://www.w3.org/1999/xlink">
+    <gmd:fileIdentifier>
+        <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "string", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
+    </gmd:fileIdentifier>
+    <gmd:language>
+        <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ md.languagecode }}{# tag="md.languagecode", name ="Metadata language", desc ="Language(s) used within the datasets", example ="eng", type = "string", multi = 0, group = "Metadata",multiline=False #}">{{ md.languagecode }}</gmd:LanguageCode>
+    </gmd:language>
+    <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
+    </gmd:hierarchyLevel>
+  {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
+    <gmd:contact>
+        <gmd:CI_ResponsibleParty>
+            <gmd:organisationName>
+                <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  inboxmulti = 1,multi = 0,type = "string",group = "Metadata",object="CI_ResponsibleParty()", inbox="Metadata point of contact",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
+            </gmd:organisationName>
+            <gmd:contactInfo>
+                <gmd:CI_Contact>
+                    <gmd:address>
+                        <gmd:CI_Address>
+                            <gmd:electronicMailAddress>
+                                <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1",  multi = 0,object="CI_ResponsibleParty()", inboxmulti = 1,group = "Metadata", inbox="Metadata point of contact",type = "email",example="image2000 at jrc.it", desc="Party responsible for the metadata information." #}</gco:CharacterString>
+                            </gmd:electronicMailAddress>
+                        </gmd:CI_Address>
+                    </gmd:address>
+                </gmd:CI_Contact>
+            </gmd:contactInfo>
+            <gmd:role>
+                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+            </gmd:role>
+        </gmd:CI_ResponsibleParty>
+    </gmd:contact>
+  {% endfor -%}
+    <gmd:dateStamp>
+        <gco:Date>{{ md.datestamp }}{# tag="md.datestamp" , name="Metadata date" , ref= "Part B 10.2" , desc= "Date that the metadata was created." , example = "2005-03-27" , type ="date" , multi= 0 , group= "Metadata" , multiline= False #}</gco:Date>
+    </gmd:dateStamp>
+    <gmd:metadataStandardName>
+        <gco:CharacterString>ISO 19115</gco:CharacterString>
+    </gmd:metadataStandardName>
+    <gmd:metadataStandardVersion>
+        <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
+    </gmd:metadataStandardVersion>
+    <gmd:identificationInfo>
+        <gmd:MD_DataIdentification>
+            <gmd:citation>
+                <gmd:CI_Citation>
+                    <gmd:title>
+                        <gco:CharacterString>{{ md.identification.title }}{# tag="md.identification.title", ref="Part B 1.1", name ="Resource title", desc ="Name by which the cited resource is known.", example ="Image2000 Product 1 (nl2) MultispectB 10.1" , multi = 0, group ="Identification", type = "string", multiline=True #}</gco:CharacterString>
+                    </gmd:title>
+          {% for d in md.identification.date -%}{# tag="for d in md.identification.date" ,name="",object="CI_Date()",group= "Temporal" , inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False #}
+                    <gmd:date>
+                        <gmd:CI_Date>
+                            <gmd:date>
+                                <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()",type = "date", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
+                            </gmd:date>
+                            <gmd:dateType>
+                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ d.type }}{# tag="d.type" , group= "Temporal" ,object="CI_Date()",type = "CI_DateTypeCode", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
+                            </gmd:dateType>
+                        </gmd:CI_Date>
+                    </gmd:date>
+          {% endfor -%}
+{% for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace) -%}{# tag="for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace)", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" #}
+                                     <gmd:identifier>
+                                        <gmd:RS_Identifier>
+                                            <gmd:code>
+                                                <gco:CharacterString>{{ cod }}{# tag="cod", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it # image2000_1_nl2_multi", type = "string", multi = 0  #}</gco:CharacterString>
+                                            </gmd:code>
+                                            <gmd:codeSpace>
+                                                <gco:CharacterString>{{ code }}{# tag="code", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code space", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it", type = "string", multi = 0 #}</gco:CharacterString>
+                                            </gmd:codeSpace>
+                                        </gmd:RS_Identifier>
+                                  </gmd:identifier>
+                      {% endfor -%}
+                </gmd:CI_Citation>
+            </gmd:citation>
+            <gmd:abstract>
+                <gco:CharacterString>{{ md.identification.abstract }}{# tag="md.identification.abstract ",ref="Part B 1.2",  name ="Resource Abstract", desc ="Brief narrative summary of the content of the resource(s).", example ="IMAGE2000 product 1 individual orthorectified scenes. IMAGE2000 was produced from ETM+ Landsat 7 satellite data and provides a consistent European coverage of individual orthorectified scenes in national map projection systems. The year 2000 was targeted as reference year, but a deviation of maximum 1-year was allowed to obtain a full coverage of Europe, which involves approximately 450 Landsat TM Frames. Where Landsat 7 data were not available, Landsat 5 data have been used instead. The spatial resolution is 25 metres for multispectral and 12.5 metres for panchromatic imagery", type = "string", multi = 0, group = "Identification", multiline=True #}</gco:CharacterString>
+            </gmd:abstract>
+      {% for co in md.identification.contact -%}{# tag="for co in md.identification.contact",object="CI_ResponsibleParty()", inboxmulti=1, group = "Responsible party",inbox="Point of contact" #}
+            <gmd:pointOfContact>
+                <gmd:CI_ResponsibleParty>
+                    <gmd:organisationName>
+                        <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1", type = "string", multi = 0, group = "Responsible party",inboxmulti=1 ,inbox="Point of contact",object="CI_ResponsibleParty()",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
+                    </gmd:organisationName>
+                    <gmd:contactInfo>
+                        <gmd:CI_Contact>
+                            <gmd:address>
+                                <gmd:CI_Address>
+                                    <gmd:electronicMailAddress>
+                                        <gco:CharacterString>{{ co.email }}{# tag="co.email",name="E-mail",ref="Part B 10.1" , group = "Metadata",inboxmulti=1, inbox="Responsible party",multi=0,example="image2000 at jrc.it",object="CI_ResponsibleParty()", type = "email",desc="Party responsible for the metadata information." #}</gco:CharacterString>
+                                    </gmd:electronicMailAddress>
+                                </gmd:CI_Address>
+                            </gmd:address>
+                        </gmd:CI_Contact>
+                    </gmd:contactInfo>
+                    <gmd:role>
+                        <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",inboxmulti=1,name="Responsible party role",type = "CI_RoleCode",object="CI_ResponsibleParty()",ref="Part B 9.2",  multi = 0, group = "Responsible party", inbox="Responsible party",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+                    </gmd:role>
+                </gmd:CI_ResponsibleParty>
+            </gmd:pointOfContact>
+      {% endfor -%}
+{% for k in md.identification.keywords -%}{# tag="for k in md.identification.keywords" ,group = "Keywords",inbox="Free keywords",inboxmulti=1 #}
+            <gmd:descriptiveKeywords>
+                <gmd:MD_Keywords>
+          {% for kw in k["keywords"] -%}{# tag='for kw in k["keywords"]',group = "Keywords",inbox="Free keywords",inboxmulti=1 #}
+                    
+                    <gmd:keyword>
+                        <gco:CharacterString>{{ kw }}{# tag="kw",ref="Part B 3.1", name ="Keyword",example="Land cover (INSPIRE Spatial Data Theme),humanCatalogueViewer (spatial data service,subcategory), water springs (AGROVOC), freshwater (GEMET Concepts)", desc ="Commonly used word(s) or formalised word(s) or phrase(s) used to describe the subject." , type = "string",inboxmulti=1, multi = 1, group = "Keywords", multiline=False, inbox="Free keywords" #} </gco:CharacterString>
+                    </gmd:keyword>
+          {% endfor -%}
+                    <gmd:thesaurusName>
+                        <gmd:CI_Citation>
+                            <gmd:title>
+                                <gco:CharacterString>{{ k["thesaurus"]["title"] }}{# tag='k["thesaurus"]["title"]', name ="Title", desc ="This citation shall include title of keywords )" , type = "string", multi = 0,inboxmulti=1, group = "Keywords", multiline=False, inbox="Free keywords" #}</gco:CharacterString>
+                            </gmd:title>
+                            <gmd:date>
+                                <gmd:CI_Date>
+                                    <gmd:date>
+                                        <gco:Date>{{ k["thesaurus"]["date"] }}{# tag='k["thesaurus"]["date"]', name ="Reference date", desc ="This citation shall include at least the title a reference date(publication, revision, creation." , type = "date",inboxmulti=1, multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" #}</gco:Date>
+                                    </gmd:date>
+                                    <gmd:dateType>
+                                        <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ k["thesaurus"]["datetype"] }}{{ k["thesaurus"]["datetype"] }}{# tag='k["thesaurus"]["datetype"]', type = "CI_DateTypeCode",name ="Date type",inboxmulti=1, desc ="Options Date of creation, Date of last revision, date of publication" , multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" #}" >{{ k["thesaurus"]["datetype"] }}</gmd:CI_DateTypeCode>
+                                    </gmd:dateType>
+                                </gmd:CI_Date>
+                            </gmd:date>
+                        </gmd:CI_Citation>
+                    </gmd:thesaurusName>
+                </gmd:MD_Keywords>
+            </gmd:descriptiveKeywords>
+      {% endfor -%}
+      {% for rc in md.identification.uselimitation -%}{# tag="for rc in md.identification.uselimitation" , group= "Constraints" ,inbox="Condition applying to access and use", inboxmulti=1 #}
+            <gmd:resourceConstraints>
+                <gmd:MD_Constraints>
+                    <gmd:useLimitation>
+                        <gco:CharacterString>{{ rc }}{# tag="rc" , name="Use limitation" , ref= "Part B 8.1" , desc= "restrictions on the access and use of a resource or metadata" , example = "no conditions apply" , type ="string" ,group= "Constraints" , multi= 0, multiline= False,inbox="Condition applying to access and use", inboxmulti=1  #}</gco:CharacterString>
+                    </gmd:useLimitation>
+                </gmd:MD_Constraints>
+            </gmd:resourceConstraints>
+      {% endfor -%}
+      {% for oc in md.identification.accessconstraints -%}{# tag="for oc in md.identification.otherconstraints" , group= "Constraints",inbox="Other restriction", inboxmulti=1  #}
+            <gmd:resourceConstraints>
+                <gmd:MD_LegalConstraints>
+                    <gmd:accessConstraints>
+                        <gmd:MD_RestrictionCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#MD_RestrictionCode" codeListValue="{{ oc }}{# tag="oc" , name="Other constraionts" , ref= "Part B 8.1" , desc= "Restrictions on the access and use of a resource or metadata" , example = "No conditions apply" , type ="MD_RestrictionCode" ,group= "Constraints" , multi= 0, multiline= False,inbox="Other restriction", inboxmulti=1  #}">{{ oc }}</gmd:MD_RestrictionCode>
+                    </gmd:accessConstraints>
+               {% endfor -%}
+      {% for ac in md.identification.accessconstraints -%}{# tag="for oc in md.identification.accessconstraints" , group= "Constraints",inbox="Limitation on public access", inboxmulti=1  #}
+                    <gmd:otherConstraints>
+                        <gco:CharacterString>{{ ac }} {# tag="ac" ,name="Access constraints", group= "Constraints",inbox="Limitations on public access", inboxmulti=1,ref= "Part B 8.2" , desc= "access constraints applied to assure the protection of privacy or intellectual property, and any special restrictionsor limitations on obtaining the resource." , example = "intellectualPropertyRights (rights to financial benefit from and control of distribution of non tangible property that is a result of creativity)." , type ="string", multi=0 ,  multiline= False #}</gco:CharacterString>
+                    </gmd:otherConstraints>
+                </gmd:MD_LegalConstraints>
+            </gmd:resourceConstraints>
+      {% endfor -%}
+      {% if md.identification.denominators|length > 0 -%}{# tag="if md.identification.denominators|length > 0", group = "Quality and Validity", inbox="Spatial resolution-scale",inboxmulti= 1 #}
+{% for den in md.identification.denominators -%}{# tag="for den in md.identification.denominators", group = "Quality and Validity", inbox="Spatial resolution-scale",inboxmulti= 1 #}
+            <gmd:spatialResolution>
+                <gmd:MD_Resolution>
+                    <gmd:equivalentScale>
+                        <gmd:MD_RepresentativeFraction>
+                            <gmd:denominator>
+                                <gco:Integer>{{ den }}{# tag="den" , name="Equivalent scale" , ref= "Part B 6.2" , desc= "level of detail expressed as the scale denominator of a comparable hardcopy map or chart" , example = "50000 (e.g. 1:50000 scale map)" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-scale", multi=0 , inboxmulti=1, multiline= False #}</gco:Integer>
+                            </gmd:denominator>
+                        </gmd:MD_RepresentativeFraction>
+                    </gmd:equivalentScale>
+                </gmd:MD_Resolution>
+            </gmd:spatialResolution>
+      {% endfor -%}
+      {% endif -%}
+      {% for (d,u) in zip(md.identification.distance, md.identification.uom) -%}{# tag="for (d,u) in zip(md.identification.distance, md.identification.uom)", group = "Quality and Validity", inbox="Spatial resolution-distance",inboxmulti= 1 #}
+            <gmd:spatialResolution>
+                <gmd:MD_Resolution>
+                    <gmd:distance>
+                        <gco:Distance uom="{{ u }}{# tag="u" , name="Units" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "m" , type ="string" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}">
+{{ d }}{# tag="d" , name="Resolution" , ref= "Part B 6.2" , desc= "Ground sample distance" , example = "25" , type ="integer" , group = "Quality and Validity" ,inbox="Spatial resolution-distance", multi=0 , inboxmulti=1, multiline= False #}</gco:Distance>
+                    </gmd:distance>
+                </gmd:MD_Resolution>
+            </gmd:spatialResolution>
+      {% endfor -%}
+      {% for lan in md.identification.resourcelanguage -%}{# tag="for lan in md.identification.resourcelanguage" , group= "Identification" ,inbox='Languages',inboxmulti=1, multiline= False #}
+            <gmd:language>
+                <gmd:LanguageCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ lan }}{# tag="lan" , name="Metadata language" , ref= "Part B 10.3" , desc= "Language used for documenting metadata." , example = "eng" , type ="LanguageCode (ISO/TS 19139)" ,multi=0,inbox='Languages',inboxmulti=1, group= "Identification" , multiline= False #}">{{ lan }}</gmd:LanguageCode>
+            </gmd:language>
+      {% endfor -%}
+      {% for tc in md.identification.topiccategory -%}{# tag="for tc in md.identification.topiccategory", inbox='Topic category',group= "Classification", multiline= False #}
+            <gmd:topicCategory>
+                <gmd:MD_TopicCategoryCode>{{ tc }}{# tag="tc" , name="Topic" , ref= "Part B 2.1" , desc= "Main theme(s) of the dataset" ,inbox='Topic category', example = "imageryBaseMapsEarthCover" , type ="MD_TopicCategory" , group= "Classification" ,  multi=0 , multiline= False #}</gmd:MD_TopicCategoryCode>
+            </gmd:topicCategory>
+      {% endfor -%}
+            <gmd:extent>
+                <gmd:EX_Extent>
+                    <gmd:geographicElement>
+                        <gmd:EX_GeographicBoundingBox>
+                            <gmd:westBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.minx }}{# tag="md.identification.extent.boundingBox.minx" , name="West Bound Longitude" , ref= "Part B 4.1" , desc= "Western-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "3.93" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:westBoundLongitude>
+                            <gmd:eastBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxx }}{# tag="md.identification.extent.boundingBox.maxx" , name="East Bound Longitude" , ref= "Part B 4.1" , desc= "Eastern-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "7.57" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:eastBoundLongitude>
+                            <gmd:southBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.miny }}{# tag="md.identification.extent.boundingBox.miny" , name="South Bound Latitude" , ref= "Part B 4.1" , desc= "Southern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "52.10" , type ="decimal" , group= "Geographic" ,multi=0 , multiline= False #}</gco:Decimal>
+                            </gmd:southBoundLatitude>
+                            <gmd:northBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxy }}{# tag="md.identification.extent.boundingBox.maxy" , name="North Bound Latitude" , ref= "Part B 4.1" , desc= "Northern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "54.10" , type ="decimal" , group= "Geographic" , multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:northBoundLatitude>
+                        </gmd:EX_GeographicBoundingBox>
+                    </gmd:geographicElement>
+                </gmd:EX_Extent>
+            </gmd:extent>
+      {% if md.identification.temporalextent_start != None -%}{# tag="if md.identification.temporalextent_start != None", group = "Temporal", inbox="Temporal Extent",inboxmulti= 0 #}
+            <gmd:extent>
+                <gmd:EX_Extent>
+                    <gmd:temporalElement>
+                        <gmd:EX_TemporalExtent>
+                            <gmd:extent>
+                                <gml:TimePeriod xsi:type="gml:TimePeriodType">
+                                    <gml:beginPosition>{{ md.identification.temporalextent_start }}{# tag="md.identification.temporalextent_start" , name="Starting date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extend", multi=0 , inboxmulti= 0, multiline= False #}</gml:beginPosition>
+                                    <gml:endPosition>{{ md.identification.temporalextent_end }}{# tag="md.identification.temporalextent_end" , name="Ending date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extend", multi=0 , inboxmulti= 0, multiline= False #}</gml:endPosition>
+                                </gml:TimePeriod>
+                            </gmd:extent>
+                        </gmd:EX_TemporalExtent>
+                    </gmd:temporalElement>
+                </gmd:EX_Extent>
+            </gmd:extent>
+      {% endif -%}
+        </gmd:MD_DataIdentification>
+    </gmd:identificationInfo>
+    <gmd:distributionInfo>
+        <gmd:MD_Distribution>
+            <gmd:distributionFormat>
+                <gmd:MD_Format>
+                    <gmd:name gco:nilReason="inapplicable"/>
+                    <gmd:version gco:nilReason="inapplicable"/>
+                </gmd:MD_Format>
+            </gmd:distributionFormat>
+            <gmd:transferOptions>
+                <gmd:MD_DigitalTransferOptions>
+          {% for ln in md.distribution.online -%}{# tag="for ln in md.distribution.online" , group= "Identification",object='CI_OnlineResource()'  #}
+                    <gmd:onLine>
+                        <gmd:CI_OnlineResource>
+                            <gmd:linkage>
+                                <gmd:URL>{{ ln.url }}{# tag="ln.url" , name="Linkage" , ref= "Part B 1.4" ,object='CI_OnlineResource()', desc= "Location (address) for on-line access using a Uniform Resource Locator address or similar addressing scheme." , example = "http://image2000.jrc.it" , type ="url" , group= "Identification" ,multi=1, multiline= False #}</gmd:URL>
+                            </gmd:linkage>
+                        </gmd:CI_OnlineResource>
+                    </gmd:onLine>
+          {% endfor -%}
+                </gmd:MD_DigitalTransferOptions>
+            </gmd:transferOptions>
+        </gmd:MD_Distribution>
+    </gmd:distributionInfo>
+    <gmd:dataQualityInfo>
+        <gmd:DQ_DataQuality>
+            <gmd:scope>
+                <gmd:DQ_Scope>
+                    <gmd:level>
+                        <gmd:MD_ScopeCode codeListValue="{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Conformity",multiline=False #}" codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode">{{ md.identification.identtype }}</gmd:MD_ScopeCode>
+                    </gmd:level>
+                </gmd:DQ_Scope>
+            </gmd:scope>
+ {% for (t,d,dt,dg) in zip(md.dataquality.conformancetitle,md.dataquality.conformancedate,md.dataquality.conformancedatetype,md.dataquality.conformancedegree) -%}{# tag="for (t,d,dt,dg) in zip(md.dataquality.conformancetitle,md.dataquality.conformancedate,md.dataquality.conformancedatetype,md.dataquality.conformancedegree)", group = "Conformity", inbox="Conformity",inboxmulti= 1 #}
+            <gmd:report>
+                <gmd:DQ_DomainConsistency xsi:type="gmd:DQ_DomainConsistency_Type">
+                    <gmd:measureIdentification>
+                        <gmd:RS_Identifier>
+                            <gmd:code>
+                                <gco:CharacterString>Conformity</gco:CharacterString>
+                            </gmd:code>
+                            <gmd:codeSpace>
+                                <gco:CharacterString>INSPIRE</gco:CharacterString>
+                            </gmd:codeSpace>
+                        </gmd:RS_Identifier>
+                    </gmd:measureIdentification>
+                    <gmd:result>
+                        <gmd:DQ_ConformanceResult xsi:type="gmd:DQ_ConformanceResult_Type">
+                            <gmd:specification>
+                                <gmd:CI_Citation>
+                                    <gmd:title>
+                                        <gco:CharacterString>{{ t }}{# tag="t" , name="Specification" , ref= "Part B 7.1" , desc= "citation of the product specification or user requirement against which data is being evaluated." , example = "INSPIRE Data Specification on orthoimagery - Guidelines" , type ="string" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= True #}</gco:CharacterString>
+                                    </gmd:title>
+                                    <gmd:date>
+                                        <gmd:CI_Date>
+                                            <gmd:date>
+                                                <gco:Date>{{ d }}{# tag="d" , name="Date" , ref= "Part B 7.1" , desc= "citation of the product specification or user requirement against which data is being evaluated." , example = "2010-04-26" , type ="date" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Date>
+                                            </gmd:date>
+                                            <gmd:dateType>
+                                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue={{ "\"%s\"" % dt }}>{{ dt }}{# tag="dt" , name="Date type" , ref= "Part B 7.1" , desc= "a date type: creation, revision or publication." , example = "publication" , type ="dateType" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gmd:CI_DateTypeCode>
+                                            </gmd:dateType>
+                                        </gmd:CI_Date>
+                                    </gmd:date>
+                                </gmd:CI_Citation>
+                            </gmd:specification>
+                            <gmd:explanation>
+                                <gco:CharacterString>See the referenced specification</gco:CharacterString>
+                            </gmd:explanation>
+                            <gmd:pass>
+                                <gco:Boolean>{{ dg }}{# tag="dg" , name="Degree/Pass" , ref= "Part B 7.2" , desc= "indication of the conformance result" , example = "True." , type ="boolean" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Boolean>
+                            </gmd:pass>
+                        </gmd:DQ_ConformanceResult>
+                    </gmd:result>
+                </gmd:DQ_DomainConsistency>
+            </gmd:report>
+      {% endfor -%}
+      <gmd:lineage>
+        <gmd:LI_Lineage>
+          <gmd:statement>
+            <gco:CharacterString>{{ md.dataquality.lineage }}{# tag="md.dataquality.lineage" , name="Lineage" , ref= "Part B 6.1" , desc= "General explanation of the data producers knowledge about the lineage of a dataset." , example = "Product 1 scenes correspond to the path/row of the Landsat orbit.." , type ="string" , group= "Quality and Validity" ,  multiline= True #}</gco:CharacterString>
+          </gmd:statement>
+        </gmd:LI_Lineage>
+      </gmd:lineage>
+    </gmd:DQ_DataQuality>
+  </gmd:dataQualityInfo>
+</gmd:MD_Metadata>

Modified: sandbox/krejcmat/src/v.info.iso.py
===================================================================
--- sandbox/krejcmat/src/v.info.iso.py	2014-08-11 05:37:43 UTC (rev 61578)
+++ sandbox/krejcmat/src/v.info.iso.py	2014-08-11 05:43:51 UTC (rev 61579)
@@ -1,17 +1,14 @@
 #!/usr/bin/env python
 # -*- coding: utf-8
 """
-MODULE:    v.info.iso
+ at module  v.info.iso
+ at brief   Module for creating metadata based on ISO from vector maps
 
-AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
 
-PURPOSE:   Module for creating metadata based on ISO
-
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
-
-           This program is free software under the GNU General Public
-           License (>=v2). Read the file COPYING that comes with GRASS
-           for details.
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
 #%option G_OPT_V_MAP
 #% key: map
@@ -19,10 +16,15 @@
 #% required: yes
 #%end
 
+#%flag
+#% key: o
+#% label: Allow to overwrite exist metadata
+#%end
+
 #%option
 #% key: profil
 #% label: Metadata profil based on ISO
-#% description: INSPIRE schema is not filled properly (unknown values are filled '$NULL')
+#% description: INSPIRE profile is not filled properly (unknown values are filled '$NULL')
 #% options: basic, inspire
 #% answer: basic
 #%end
@@ -44,7 +46,6 @@
 
 
 def main():
-
     if not options['destination']:
         destination = None
     else:
@@ -55,17 +56,24 @@
     else:
         mdout = options['mdout']
 
-    # create instance of metadata in owslib
     md = GrassMD(options['map'], 'vector')
-
     if options['profil'] == 'inspire':
         md.createGrassInspireISO()
-        xml_file = md.saveXML(options['destination'], options['mdout'])
-        md.readXML(xml_file)
-        print md.validate_inspire()
+        xml_file = md.saveXML(path=destination,
+                              xml_out_name=mdout,
+                              overwrite=flags['o'])
+        if xml_file is not False:
+            md.readXML(xml_file)
+            print md.validate_inspire()
+
     else:
         md.createGrassBasicISO()
-        md.saveXML(options['destination'], options['mdout'])
+        xml_file = md.saveXML(path=destination,
+                              xml_out_name=mdout,
+                              overwrite=flags['o'])
+        if xml_file is not False:
+            md.readXML(xml_file)
+            print md.validate_basic()
 
 if __name__ == "__main__":
     options, flags = parser()



More information about the grass-commit mailing list