Re: [Generateds-discuss] How to create/ generate new xml from generated API
Brought to you by:
dkuhlman
From: Dave K. <dku...@da...> - 2022-06-06 19:23:24
|
Daniel, What? You don't seem like a Python newbie to me. About the error -- I believe that exception message is telling us that it wants a different type for the value of `testResults01.Personnel.set_SystemOperator`. Short version -- see attached file `test01.py`. Long attempted explanation -- see the following: In the XML schema (`TestResults.xsd`), search for "SystemOperator". You will find the following: <xs:element name="SystemOperator" type="Person"> <xs:annotation> <xs:documentation>Identification information for the operator of the ATE.</xs:documentation> </xs:annotation> </xs:element> The `type="Person"` tells us it want an instance of class `Person`. So, look at the definition of class `Person` in the module that you generated with `generateDS.py` (`atdsApi.py`, I believe). We have to construct a instance of class Person. And, since class `Person` contains an `Address`, we can construct an instance of class `Address`. I've attached a file (`test01.py`) with a modified version of your code. And, here is a snippet mailingaddress = lib.MailingAddress( Address1="123 Pretty Lane", City="Bigcity", State="Arizona", Country="USA", PostalCode="98765", ) sysOp = lib.Person( name="Dan", Address=mailingaddress, email="da...@so...", phone="123.456.7890", # etc ) testResults01.Personnel.set_SystemOperator(sysOp) print (testResults01.Personnel.get_SystemOperator()) testResults01.export(sys.stdout, 0) You can get clues about this if you look in the `build`, `_buildAttributes`, and `_buildChildren` methods in classes `PersonnelType`, `Person`, `Operator`, etc. Notice that, for the `SystemOperator` member, it creates and instance of class `Person`. And, since class `Person` is a subclass of class `Operator`, you may want to look at the implementation of class `Operator` in `atdsApi.py`. It's a bit confusing. It is to me at least. But, then, I suppose XML and XML schema is supposed to be. Sigh. Hope this helps. Dave Quoting "Dewitte, Daniel W (US)" <dan...@ba...>: > Hi Dave, > > Thank you for the pointers, yes this worked great for me. I still > get a few errors when creating the API but I will worry about those > when I get to the external validator I have to use to ensure that > everything is working. > > I also wanted to thank you, I am new to Python with this being my > first major project. I have played around with an RPi but nothing > major like up to this point. So some of the syntax and ways that > Python uses is new to me and I am trying to learn. > > I do have some more questions at the moment and then I think I will > be more then off and running on this next phase of this project. > 1) You have been able to show me on how to create the initial > instance of the Root Element, is that correct? As long as the line > "testResults01 = lib.TestResults()" calls the root element class. > Is that correct? > > 2) In the def __init__ of that element, I see that the input > arguments are the attributes and child elements of that root > element. See attached image. > The first two in the init at the elements attributes, the rest are > child elements. I can set the attributes by just replacing "None" > with their values (hardcoded or generated). How to I generate the > child elements (i.e. "Personnel") so that I can start setting their > attributes and parameters? > > I have tried the following code: > import sys > import atdsApi as lib > > testResults01 = lib.TestResults(uuid = "1", securityClassification = > "Unclassified", > Personnel = lib.PersonnelType()) > print (testResults01.get_uuid()) > print (testResults01.get_securityClassification()) > testResults01.export(sys.stdout, 0) > > I get this result: > 1 > Unclassified > <c:TestResults xmlns:None="http://www.ieee.org/ATML/2006/Common" > xmlns:c="http://www.ieee.org/ATML/2006/Common" uuid="1" > securityClassification="Unclassified"> > <c:Personnel/> > </c:TestResults> > > When I try to then go and set the attributes of Personnel which is > controlled by PersonnelType() I get an error. > Code: > import sys > import atdsApi as lib > > testResults01 = lib.TestResults(uuid = "1", securityClassification = > "Unclassified", > Personnel = lib.PersonnelType()) > print (testResults01.get_uuid()) > print (testResults01.get_securityClassification()) > testResults01.Personnel.set_SystemOperator("Dan") > print (testResults01.Personnel.get_SystemOperator()) > testResults01.export(sys.stdout, 0) > > Error: > 1 > Unclassified > Dan > <c:TestResults xmlns:None="http://www.ieee.org/ATML/2006/Common" > xmlns:c="http://www.ieee.org/ATML/2006/Common" uuid="1" > securityClassification="Unclassified"> > <c:Personnel> > Traceback (most recent call last): > > File "H:\C4ISR S2 NPI\Projects\Voice of the Process\ATDS TDR > Importer - Python\ATDS File Creator\generateDS_xmlCreate.py", line > 16, in <module> > testResults01.export(sys.stdout, 0) > > File "H:\C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR > Importer - Python/ATDS File Creator\atdsApi.py", line 1314, in export > self._exportChildren(outfile, level + 1, namespaceprefix_, > namespacedef_, name_='TestResults', pretty_print=pretty_print) > > File "H:\C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR > Importer - Python/ATDS File Creator\atdsApi.py", line 1342, in > _exportChildren > self.Personnel.export(outfile, level, namespaceprefix_, > namespacedef_='', name_='Personnel', pretty_print=pretty_print) > > File "H:\C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR > Importer - Python/ATDS File Creator\atdsApi.py", line 10284, in export > self._exportChildren(outfile, level + 1, namespaceprefix_, > namespacedef_, name_='PersonnelType', pretty_print=pretty_print) > > File "H:\C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR > Importer - Python/ATDS File Creator\atdsApi.py", line 10304, in > _exportChildren > self.SystemOperator.export(outfile, level, namespaceprefix_, > namespacedef_='', name_='SystemOperator', pretty_print=pretty_print) > > AttributeError: 'str' object has no attribute 'export' > > By reading the error it looks like it is actually on the export > function and not the set function as it is setting the System > Operator. > Any ideas? > > I am sure to have more questions soon. > Thank you again, > > Daniel DeWitte > > T: +1-603-885-2602 > M: +1-603-759-4476 > E: dan...@ba... > > -----Original Message----- > From: Dave Kuhlman <dku...@da...> > Sent: Thursday, June 2, 2022 3:56 PM > To: Dewitte, Daniel W (US) <dan...@ba...> > Cc: Gen...@li... > Subject: Re: [Generateds-discuss] How to create/ generate new xml > from generated API > > External Email Alert > > This email has been sent from an account outside of the BAE Systems network. > > Please treat the email with caution, especially if you are requested > to click on a link, decrypt/open an attachment, or enable macros. > For further information on how to spot phishing, access > “Cybersecurity OneSpace Page” and report phishing by clicking the > button “Report Phishing” on the Outlook toolbar. > > > Daniel, > > Thanks for providing that info, command line, generated module, etc. > > When you run `generateDS.py`, the "-o" option means generate a main > module, and the "-s" option says generate a subclass module. The > "--super=xxxx" tells `generateDS.py` to generate an `import` > statement in the subclass module that imports module `atdsApi.py`. > Since you have given the same name for "-o" and "-s" that module > imports itself. And, maybe, the main module is over-written by the > subclass module. > > I don't know what your needs are, but it's likely that you do not > want to use either "-s" or "--super" command line options. If you > do not need the subclass module, do not generate it. > > My example command line does not make this very clear because, > although it does use different names for "-o" and "-s", there is > only one letter difference. Sorry for the confusion. > > Try running the following instead: > > $ python generateDS.py -f -o atdsApi.py --member-specs=dict > --export="write etree validate" TestResults.xsd > > Then the following Python code should work: > > import sys > import atdsApi as lib > testResults01 = lib.TestResult() > testResults01.export(sys.stdout, 0) > > Notice that I added "sys." in front of "stdout". > > Hope this helps. Let me know if/when you have more questions. > > Dave > > > Quoting "Dewitte, Daniel W (US)" <dan...@ba...>: > >> Hi Dave, >> >> Thank you for your quick response, so far the first part of what you >> showed me is working, I do get some warnings though. It looks like >> because the TestResults.xsd names multiple namespace prefix's it is >> not carrying the "c:" prefix. >> >> 1) H:\Python Training\GenerateDS_Docs>python generateDS.py -f -o >> atdsApi.py -s atdsApi.py --super=atdsApi --member-specs=dict >> --export="write etree validate" TestResults.xsd >> *** No suitable ns prefix for element "<XschemaElement name: >> "Outcome" type: "Outcome">". >> WARNING - H:\Python Training\GenerateDS_Docs\generateDS.py - _lookupNS >> - Unknown namespace prefix "c" used. >> WARNING - H:\Python Training\GenerateDS_Docs\generateDS.py - _lookupNS >> - Unknown namespace prefix "c" used. >> WARNING - H:\Python Training\GenerateDS_Docs\generateDS.py - _lookupNS >> - Unknown namespace prefix "c" used. >> >> 2) I created a new .py file and have the following: >> # -*- coding: utf-8 -*- >> """ >> Created on Wed May 25 11:02:45 2022 >> >> @author: daniel.dewitte >> """ >> import sys >> import atdsApi as lib >> >> testResults01 = lib.TestResult() >> testResults01.export(stdout, 0) >> >> When I try to run this .py I get the following errors: >> runfile('H:/C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR >> Importer - Python/ATDS File Creator/generateDS_xmlCreate.py', >> wdir='H:/C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR Importer >> - Python/ATDS File Creator') Traceback (most recent call last): >> >> File "H:\C4ISR S2 NPI\Projects\Voice of the Process\ATDS TDR >> Importer - Python\ATDS File Creator\generateDS_xmlCreate.py", line 8, >> in <module> >> import atdsApi as lib >> >> File "H:\C4ISR S2 NPI/Projects/Voice of the Process/ATDS TDR >> Importer - Python/ATDS File Creator\atdsApi.py", line 68, in <module> >> class TestResultsSub(supermod.TestResults): >> >> AttributeError: partially initialized module 'atdsApi' has no >> attribute 'TestResults' (most likely due to a circular import) >> >> Attached the api.py for reference. >> >> Thanks, >> Daniel DeWitte >> >> -----Original Message----- >> From: Dave Kuhlman <dku...@da...> >> Sent: Wednesday, June 1, 2022 7:08 PM >> To: Dewitte, Daniel W (US) <dan...@ba...> >> Cc: Gen...@li... >> Subject: Re: [Generateds-discuss] How to create/ generate new xml from >> generated API >> >> External Email Alert >> >> This email has been sent from an account outside of the BAE Systems network. >> >> Please treat the email with caution, especially if you are requested >> to click on a link, decrypt/open an attachment, or enable macros. >> For further information on how to spot phishing, access “Cybersecurity >> OneSpace Page” and report phishing by clicking the button “Report >> Phishing” on the Outlook toolbar. >> >> >> Daniel, >> >> Thanks for taking the time to report this. >> >> Here is what I've tried so far: >> >> 1. I copied TestResults.xml and Common.xsd to a directory. >> >> 2. I ran the following command: >> >> ./generateDS.py -f -o tmp01sup.py -s tmp01sub.py --super >> tmp01sup --member-specs=dict '--export=write etree validate' >> TestResults.xsd >> >> That generated a module `tmp01sup.py`. >> >> 3. So, I started IPython (the plain Python interactive prompt would >> also work) and did this: >> >> [ins] In [1]: import tmp01sup as lib >> >> Which also worked. >> >> 4. Then I created an instance of a class in the generated module: >> >> [ins] In [5]: testresults01 = lib.TestResult() >> [ins] In [6]: testresults01.export(sys.stdout, 0) >> <c:TestResult >> xmlns:None="http://www.ieee.org/ATML/2006/Common" >> xmlns:c="http://www.ieee.org/ATML/2006/Common" /> >> >> Which also seemed to work. >> >> So, now I've got to read your message a bit more carefully so that I >> can figure out what is wrong for your case and how to fix it. >> >> I do not have the file `collect_schema_locations.py`, which you show >> in your message as generating an exception. So, I can't test that. >> Did you generate that file with `generateDS.py`? >> >> However the exception "TypeError: empty namespace prefix is not >> supported in XPath" seems to occur when you have a key in the nsmap >> that is `None`. Try removing it. Then do the `xpath` search: >> >> [ins] In [23]: nsmap = root.nsmap >> [ins] In [24]: nsmap >> Out[24]: >> {'xs': 'http://www.w3.org/2001/XMLSchema', >> 'c': 'http://www.ieee.org/ATML/2006/Common', >> None: 'http://www.ieee.org/ATML/2007/TestResults'} >> [ins] In [25]: nsmap.pop(None) >> Out[25]: 'http://www.ieee.org/ATML/2007/TestResults' >> [ins] In [26]: nsmap >> Out[26]: >> {'xs': 'http://www.w3.org/2001/XMLSchema', >> 'c': 'http://www.ieee.org/ATML/2006/Common'} >> [ins] In [27]: root.xpath('xs:import', namespaces=nsmap) >> Out[27]: [<Element {http://www.w3.org/2001/XMLSchema}import at >> 0x7faf573acac0>] >> >> Does that help with your work? >> >> By the way, the "--one-file-per-xsd" capability is something that I >> do not understand, myself. That code was contributed by someone else. >> >> Dave >> >> >> Quoting "Dewitte, Daniel W (US) via Generateds-discuss" >> <gen...@li...>: >> >>> Here are the actual files this time :) >>> >>> Daniel DeWitte >>> >>> From: Dewitte, Daniel W (US) >>> Sent: Wednesday, June 1, 2022 1:06 PM >>> To: 'Gen...@li...' >>> <Gen...@li...> >>> Subject: How to create/ generate new xml from generated API >>> >>> Hi Dave, >>> >>> This is one of the better tools that I have found and I think the only >>> one that can work the way I need it too, I just need some help with >>> getting to the finish line. >>> >>> My goal is generate a new .xml using a known schema .xsd with Python >>> as the base language (required). I have 13 different reports that all >>> have a different format that are generated on a constant basis that I >>> need to import into a known .xsd format for upload to a database. >>> >>> I believe I either want to use the build methods, or the "one-per" >>> options, but I can't get either of them to work. I asked about the >>> build method problem on stackover flow here: Stackoverflow - Creating >>> a new XML from an XSD using GenerateDS and >>> Python<https://stackoverflow.com/questions/72397436/creating-a-new-xml >>> -from-an-xsd-using-generateds-and-python> >>> >>> But I am not sure that the build method is what I want to use. >>> >>> When I try the "one-per" I get the following errors: >>> Command line method, I believe this error is due to that the .xsd is >>> in a UTF-8 encoding. How do I get this to work with UTF-8 encoding? >>>> (base) H:\Python Training\GenerateDS_Docs>python generateds.py >>>> --one-file-per-xsd --output-directory="OnePer" >>>> --module-suffix="One" TestResults.xsd Traceback (most recent call >>>> last): >>>> File "H:\Python Training\GenerateDS_Docs\generateds.py", line 9906, >>>> in <module> >>> main() >>>> File "H:\Python Training\GenerateDS_Docs\generateds.py", line 9872, >>>> in main >>> parseAndGenerate( >>>> File "H:\Python Training\GenerateDS_Docs\generateds.py", line 9318, >>>> in parseAndGenerate >>> parser.parse(rootFile) >>>> File "C:\EngTools\Anaconda3\lib\xml\sax\expatreader.py", line 111, in >>>> parse >>> xmlreader.IncrementalParser.parse(self, source) >>>> File "C:\EngTools\Anaconda3\lib\xml\sax\xmlreader.py", line 123, in >>>> parse >>> buffer = file.read(self._bufsize) >>>> File "C:\EngTools\Anaconda3\lib\encodings\cp1252.py", line 23, in >>>> decode >>> return codecs.charmap_decode(input,self.errors,decoding_table)[0] >>>> UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in >>>> position 4013: character maps to <undefined> >>> >>> Approach 2 - Extraction and Generation Utilities: >>>> (base) h:\Python Training\GenerateDS_Docs\utils>python >>>> collect_schema_locations.py --force --verbose TestResults.xsd >>>> testJson.txt Traceback (most recent call last): >>>> File "h:\Python >>>> Training\GenerateDS_Docs\utils\collect_schema_locations.py", line >>>> 157, in <module> >>> main() >>>> File "h:\Python >>>> Training\GenerateDS_Docs\utils\collect_schema_locations.py", line >>>> 148, in main >>> extract_and_generate(infile, outfile, extract_locations_fn, >>> options) >>>> File "h:\Python >>>> Training\GenerateDS_Docs\utils\collect_schema_locations.py", line 86, >>>> in extract_and_generate >>> locations = extract_locations(infile, options) >>>> File "h:\Python >>>> Training\GenerateDS_Docs\utils\collect_schema_locations.py", line 50, >>>> in extract_locations >>> elements = root.xpath('xs:import', namespaces=root.nsmap) >>>> File "src/lxml/etree.pyx", line 1579, in lxml.etree._Element.xpath >>>> File "src/lxml/xpath.pxi", line 259, in >>>> lxml.etree.XPathElementEvaluator.__init__ >>>> File "src/lxml/xpath.pxi", line 131, in >>>> lxml.etree._XPathEvaluatorBase.__init__ >>>> File "src/lxml/xpath.pxi", line 55, in >>>> lxml.etree._XPathContext.__init__ File "src/lxml/extensions.pxi", >>>> line 81, in lxml.etree._BaseContext.__init__ >>>> TypeError: empty namespace prefix is not supported in XPath >>> >>> Attached are the .xsd that I am using. TestResults.xsd references >>> Common.xsd. >>> >>> Any help on getting started with my overall goal will be much >>> appreciated. I am looking to create a new XML from a known .xsd and >>> add in the elements and child elements and attributes as needed. >>> >>> Thank you for the help, >>> Daniel DeWitte >> >> >> >> -- >> Dave Kuhlman >> http://www.davekuhlman.org > > > > -- > Dave Kuhlman > http://www.davekuhlman.org -- Dave Kuhlman http://www.davekuhlman.org |