Changeset ea67541 in sasview


Ignore:
Timestamp:
Apr 3, 2014 3:22:58 AM (10 years ago)
Author:
Jeff Krzywon <jeffery.krzywon@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
caf273b
Parents:
307fa4f
Message:

Fix for ticket #204 - processing instructions were not being set properly when saving as cansas data file.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/sans/dataloader/readers/cansas_reader.py

    rb65ae90 rea67541  
    2828 
    2929_ZERO = 1e-16 
     30PREPROCESS = "xmlpreprocess" 
    3031HAS_CONVERTER = True 
    3132try: 
     
    212213                            data1d.filename = name 
    213214                            data1d.meta_data["loader"] = "CanSAS 1D" 
     215                             
     216                            # Get all preprocessing events 
     217                            self.reader.setProcessingInstructions() 
     218                            data1d.meta_data[PREPROCESS] = \ 
     219                                    self.reader.processingInstructions 
     220                             
     221                            # Parse the XML file 
    214222                            return_value, extras = \ 
    215223                                self._parse_entry(entry, ns, data1d) 
     
    247255        return None 
    248256     
    249     def _create_unique_key(self, dictionary, name, i): 
     257    def _create_unique_key(self, dictionary, name, i = 0): 
    250258        """ 
    251259        Create a unique key value for any dictionary to prevent overwriting 
    252          
     260        Recurses until a unique key value is found. 
    253261         
    254262        :param dictionary: A dictionary with any number of entries 
    255263        :param name: The index of the item to be added to dictionary 
    256         :param i: The number to be appended to the name 
     264        :param i: The number to be appended to the name, starts at 0 
    257265        """ 
    258266        if dictionary.get(name) is not None: 
     
    291299                    if HAS_CONVERTER == True: 
    292300                        try: 
    293                             ## Check local units - bad units should raise KeyError 
     301                            ## Check local units - bad units raise KeyError 
    294302                            Converter(local_unit) 
    295303                            data_conv_q = Converter(attr['unit']) 
     
    347355                            CANSAS_NS.get(self.cansas_version).get("ns"), "}") 
    348356        unit = '' 
     357        tagname = '' 
     358        tagname_original = '' 
    349359         
    350360        # Go through each child in the parent element 
     
    440450                        exec item 
    441451                # Don't bother saving empty information unless it is a float 
    442                 if cs_values.ns_variable is not None and node_value is not None and \ 
     452                if cs_values.ns_variable is not None and \ 
     453                            node_value is not None and \ 
    443454                            node_value.isspace() == False: 
    444455                    # Format a string and then execute it. 
    445                     store_me = cs_values.ns_variable.format("data1d", node_value, tagname) 
     456                    store_me = cs_values.ns_variable.format("data1d", \ 
     457                                                            node_value, tagname) 
    446458                    exec store_me 
    447459                # Get attributes and process them 
     
    503515         
    504516        main_node = doc.createElement("SASroot") 
    505         if self.cansas_version == "1.1": 
    506             pi = doc.createProcessingInstruction('xml-stylesheet', \ 
    507                                     'type="text/xsl" href="cansasxml-html.xsl"') 
    508             root = doc.firstChild 
    509             doc.insertBefore(pi, root) 
     517         
     518        doc = self.setProcessingInstructions(doc, datainfo.meta_data[PREPROCESS]) 
    510519        main_node.setAttribute("version", self.cansas_version) 
    511520        main_node.setAttribute("xmlns", ns) 
     
    789798        fd.write(doc.toprettyxml()) 
    790799        fd.close() 
     800     
     801    ## Once I convert the writer to lxml from minidom 
     802    ## This can be moved into xml_reader 
     803    def setProcessingInstructions(self, minidomObject, dic): 
     804        xmlroot = minidomObject.firstChild 
     805        for item in dic: 
     806            pi = minidomObject.createProcessingInstruction(item, dic[item]) 
     807            minidomObject.insertBefore(pi, xmlroot) 
     808        return minidomObject 
     809     
     810     
  • src/sans/dataloader/readers/xml_reader.py

    r76cd1ae rea67541  
    1414 
    1515from lxml import etree 
    16 parser = etree.ETCompatXMLParser() 
     16parser = etree.ETCompatXMLParser(remove_comments=True, remove_pis=False) 
    1717 
    1818class XMLreader(): 
     
    2323    schema = None 
    2424    schemadoc = None 
     25    processingInstructions = None 
    2526     
    2627    def __init__(self, xml = None, schema = None, root = None): 
    2728        self.xml = xml 
    2829        self.schema = schema 
     30        self.processingInstructions = {} 
    2931        if xml is not None: 
    3032            self.setXMLFile(xml, root) 
     
    4850     
    4951    def setXMLFile(self, xml, root = None): 
     52        """ 
     53        Set the XML file and parse 
     54        """ 
    5055        try: 
    5156            self.xml = xml 
     
    5863     
    5964    def setSchema(self, schema): 
     65        """ 
     66        Set the schema file and parse 
     67        """ 
    6068        try: 
    6169            self.schema = schema 
     
    7886    def findInvalidXML(self): 
    7987        """ 
    80         Finds the first offending element that should not be present in an XML file 
     88        Finds the first offending element that should not be present in XML file 
    8189        """ 
    8290        firstError = "" 
     
    96104        self.setSchema(self.schema) 
    97105         
     106    def toString(self, etreeElement): 
     107        """ 
     108        Converts and etree element into a string 
     109        """ 
     110        return etree.tostring(etreeElement) 
     111     
     112    def setProcessingInstructions(self): 
     113        """ 
     114        Take out all processing instructions and create a dictionary from them 
     115        """ 
     116        dic = {} 
     117        pi = self.xmlroot.getprevious() 
     118        while pi is not None: 
     119            attr = {} 
     120            pi_name = "" 
     121            pi_string = self.toString(pi) 
     122            if isinstance(pi_string, str): 
     123                pi_string = pi_string.replace("<?", "").replace("?>", "") 
     124                split = pi_string.split(" ", 1) 
     125                pi_name = split[0] 
     126                attr = split[1] 
     127            new_pi_name = self._create_unique_key(dic, pi_name) 
     128            dic[new_pi_name] = attr 
     129            pi = pi.getprevious() 
     130        self.processingInstructions = dic 
     131         
     132    def _create_unique_key(self, dictionary, name, i = 0): 
     133        """ 
     134        Create a unique key value for any dictionary to prevent overwriting 
     135        Recurses until a unique key value is found. 
     136         
     137        :param dictionary: A dictionary with any number of entries 
     138        :param name: The index of the item to be added to dictionary 
     139        :param i: The number to be appended to the name, starts at 0 
     140        """ 
     141        if dictionary.get(name) is not None: 
     142            i += 1 
     143            name = name.split("_")[0] 
     144            name += "_{0}".format(i) 
     145            name = self._create_unique_key(dictionary, name, i) 
     146        return name 
     147     
     148         
  • test/sansdataloader/test/isis_1_0_write_test.xml

    rc6ca23d rea67541  
    11<?xml version="1.0" ?> 
     2<?xml-stylesheet type="text/xsl" href="cansasxml-html.xsl" ?> 
    23<SASroot version="1.0" xmlns="cansas1d/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="cansas1d/1.0 http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd"> 
    34        <SASentry> 
  • test/sansdataloader/test/isis_1_1_write_test.xml

    rc6ca23d rea67541  
    11<?xml version="1.0" ?> 
    2 <?xml-stylesheet type="text/xsl" href="cansasxml-html.xsl"?> 
     2<?xml-stylesheet type="text/xsl" href="cansas1d.xsl" ?> 
    33<SASroot version="1.1" xmlns="urn:cansas1d:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:cansas1d:1.1 http://www.cansas.org/formats/1.1/cansas1d.xsd"> 
    44        <SASentry> 
  • test/sansdataloader/test/utest_cansas.py

    rc6ca23d rea67541  
    2020 
    2121from lxml import etree 
    22 import xml.dom.minidom 
     22from xml.dom import minidom 
    2323  
    2424CANSAS_FORMAT = cansasConstants.CANSAS_FORMAT 
     
    5050            name = self.get_number_of_entries(dictionary, name, i) 
    5151        return name 
    52      
     52        
    5353 
    5454    def test_xml_validate(self): 
     
    8282        self.assertTrue(data.title == "TK49 c10_SANS") 
    8383        self.assertTrue(data.x.size == 138) 
    84         self.assertTrue(len(data.meta_data) == 2) 
     84        self.assertTrue(len(data.meta_data) == 3) 
    8585        self.assertTrue(data.detector[0].distance_unit == "mm") 
    8686        self.assertTrue(data.detector[1].distance_unit == "mm") 
     
    9090        self.assertTrue(data.detector[1].distance == 4145.02) 
    9191        self.assertTrue(data.process[0].name == "Mantid generated CanSAS1D XML") 
     92        self.assertTrue(data.meta_data["xmlpreprocess"]["xml-stylesheet"] != None) 
    9293         
    9394     
     
    155156        self.assertFalse(reader7.validateXML()) 
    156157         
    157      
     158        
    158159    def test_old_cansas_files(self): 
    159160        reader1 = XMLreader(self.cansas1d, self.schema_1_0) 
    160161        self.assertTrue(reader1.validateXML()) 
     162        file_loader = Loader() 
     163        file1 = file_loader.load(self.cansas1d) 
    161164        reader2 = XMLreader(self.cansas1d_units, self.schema_1_0) 
    162165        self.assertTrue(reader2.validateXML()) 
     
    166169        self.assertTrue(reader4.validateXML()) 
    167170         
    168      
    169171    def test_save_cansas_v1_0(self): 
    170172        filename = "isis_1_0_write_test.xml" 
     
    186188            self._check_data(written_data) 
    187189         
    188  
     190         
     191    def test_processing_instructions(self): 
     192        reader = XMLreader(self.isis_1_1, self.schema_1_1) 
     193        valid = reader.validateXML() 
     194        if valid: 
     195            ## find the processing instructions and make into a dictionary 
     196            dic = self.getProcessingInstructions(reader) 
     197            self.assertTrue(dic == {'xml-stylesheet': 'type="text/xsl" href="cansas1d.xsl" '}) 
     198             
     199            xml = "<test><a><b><c></c></b></a></test>" 
     200            xmldoc = minidom.parseString(xml) 
     201             
     202            ## take the processing instructions and put them back in 
     203            xmldoc = self.setProcessingInstructions(xmldoc, dic) 
     204            xml_output = xmldoc.toprettyxml() 
     205             
     206     
     207    def setProcessingInstructions(self, minidomObject, dic): 
     208        xmlroot = minidomObject.firstChild 
     209        for item in dic: 
     210            pi = minidomObject.createProcessingInstruction(item, dic[item]) 
     211            minidomObject.insertBefore(pi, xmlroot) 
     212        return minidomObject 
     213     
     214     
     215    def getProcessingInstructions(self, XMLreaderObject): 
     216        dict = {} 
     217        pi = XMLreaderObject.xmlroot.getprevious() 
     218        i = 0 
     219        while pi is not None: 
     220            attr = {} 
     221            pi_name = "" 
     222            pi_string = etree.tostring(pi) 
     223            if isinstance(pi_string, str): 
     224                pi_string = pi_string.replace("<?", "").replace("?>", "") 
     225                split = pi_string.split(" ", 1) 
     226                pi_name = split[0] 
     227                attr = split[1] 
     228            dict[pi_name] = attr 
     229            pi = pi.getprevious() 
     230        return dict 
     231         
    189232if __name__ == '__main__': 
    190233    unittest.main()     
  • test/sansdataloader/test/write_test.xml

    r75eeb425 rea67541  
    11<?xml version="1.0" ?> 
     2<?xml-stylesheet type="text/xsl" href="example.xsl" ?> 
    23<SASroot version="1.0" xmlns="cansas1d/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="cansas1d/1.0 http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd"> 
    34        <SASentry> 
Note: See TracChangeset for help on using the changeset viewer.