Rob,

I won't be able to do a fix one this soon.  I'm leaving on a
two-week vacation in two days, and this issue will require a bit
more work than I'll have time for before then.  I'm hoping you can
make do with what you've got, at least temporarily..

In the meantime, here are a few notes on my analysis of the problem.
Maybe it will help remind me of what to look at when I get back.
Or, perhaps will help someone solve this.

A few preliminaries:

- Namespace prefixes can be arbitrarily chosen and modified, if done
  consistently.

- A single schema can be defined in multiple files/docs, some of
  which define different namespaces.  The same name (a top level
  `xs:element` or `xs:complexType`) can be defined in multiple
  namespaces.  The directive `xs:import` is used to pull these
  separate documents/namespaces into a single schema.

- A file or document can define a single namespace.  The
  `targetNamespace` attribute is used to specify that namespace.
  And, the `xmlns:xxx` attribute is used to associate a namespace
  prefix with that (target) namespace.

- `generateDS.py` uses `process_includes.py` to pull the separate
  documents that define a schema into a single (Lxml) element tree.
  It does this by traversing each `xs:import` and `xs:include`
  directive, recursively.

Looking for what to fix and how to fix it:

1. What is the problem? -- Some elements are being exported with the
   wrong namespace prefix.  It's the namespace prefix of the
   enclosing element.

2. Where does this happen? -- The code that causes the error is
   generated by `generateExportChildren` and several functions that
   it calls: possiblly `generateExportFn_1`, `generateExportFn_2`, and
   `generateExportFn_3`.

3. When I use `ipdb`/`pdb` and put a break-point in those functions,
   I find that the information we need about the namespace is not
   there.  (Note that `generateDS.py` maintains a dictionary that
   maps namespaces to namespace prefixes; so, if we had the
   namespace, we could look up the prefix.)

4. Possible places where we'd need to do a fix:

   - Maybe the method `startElement` in class `XschemaElement` is
     not collecting the namespace information we need.

   - And, perhaps `process_includes.py` is not saving the
     information we need.  Note that, since `process_includes.py` 
     mashes all those documents into a single document and element
     tree, the `targetNamespace` (which is implied for each schema
     document) is lost.  Perhaps `process_includes.py` could be
     enhanced so that it collects information (a dictionary?) that
     associates the target namespace with the (top level) elements
     (`xs:element` and `xs:complexType`) defined within it.

And, we should keep in mind that, since XML schema namespaces enable
you to define the same name differently in multiple namespaces and
since `generateDS.py` generates code that define classes in a
*single* Python namespace, we still will not be able to handle those
duplicate (top-level type names).

More on this next year.  In the meantime, hope you have a great
holiday.  And, thanks much for your work and help with this.

Dave

On Thu, Dec 14, 2017 at 04:44:34PM -0800, Rob Calvert wrote:
> v2.29.4 allowed me to remove some of my hand-edits, and it
> definitely seems to have fixed the problem that required me to set
> original_tagname_. Thanks! (I see what you mean about how the
> passed “name_” parameter was the cause of the inapproprately-named
> tags.)
> 
> I still find that I'm forced to hand-edit the generated
> oadr_20b.py in a few places, though:
> 
> The PayloadFloat class exports tags in the “oadr” namespace; it
> should export tags in the “ei” namespace.  The PowerReal class
> exports tags in the “oadr” namespace; it should export tags in the
> “power” namespace.
> The intervals class lacks a “strm” namespacedef.
> 
> Those first two classes participate in the schema’s polymorphism
> (they’re concrete subclasses attached to variables named for the
> superclass), so I’m guessing that this wrong-namespace issue is
> also caused by the polymorphism, but is perhaps only marginally
> related to the problem that you just solved. 
> 
> — Rob
> 
> > On Dec 14, 2017, at 3:07 PM, Dave Kuhlman <dkuhl...@davekuhlman.org> wrote:
> > 
> > Rob,
> > 
> > I've made a fix for the export of child elements declared as
> > instances of an abstract type.  The new code is here:
> > 
> >    https://bitbucket.org/dkuhlman/generateds
> > 
> > Could you give it a try and see if it fixes this issue.  I
> > eye-balled the generated code.  That seems to be what we want.  And,
> > I also adapted the oadr_test.py file that you sent so that I could
> > run it with code generated before and after this fix.  That seems to
> > produce what we want.
> > 
> > So, it seems to fix our problem and it does not seem to create new
> > problems.
> > 
> > A few more comments follow ...
> > 
> > Thanks for your notes, below.  They helped focus me on where I
> > believe the problem is.
> > 
> > You are correct that we should not have to use original_tagname_.
> > We are using polymorphism here, and the concrete (non-abstract)
> > instance knows its class and knows how it should export itself.
> > 
> > The problem, I believe, is that the containing class (IntervalType,
> > for example), when it asks its child to export itself, is passing in
> > its own value for the `name_` parameter and, by doing so, is
> > overriding the correct value, which is the default for the `name_`
> > parameter.
> > 
> > In the generated export methods (`export` and `exportChildren`, in
> > particular), the `original_tagname_` class variable, if not None, is
> > used to override the value of `name_`.  That's why your temporary
> > fix works.  So, if I can straighten out the value of `name_`, which
> > is being passed to the child, perhaps we'll have a fix.
> > 
> > Sometimes, the container needs to pass the `name_` parameter.
> > But, if the (static) type of the child is an abstract class/type,
> > then, as you mention below, the container can't know the correct
> > value.  I'll focus on that.
> > 
> > Dave
> > 
> > On Wed, Dec 13, 2017 at 09:35:32PM -0800, Rob Calvert wrote:
> >> Thanks for your efforts in trying to unravel why this problem occurred. 
> >> 
> >> I think you ended up saying this already, but let me try to
> >> re-state things just for clarity. On the sending end, I
> >> instantiate concrete subclasses (oadrReportPayload, PayloadFloat,
> >> oadrPayloadResourceStatus), but I have to attach those instances
> >> to their containers using variables (streamPayloadBase,
> >> payloadBase) that are named for the abstract superclass -- those
> >> are the variable names that have been provided in the generated
> >> oadr_20b.py. It makes sense to me that those are the variable
> >> names; the variables can’t be named for the concrete classes,
> >> since due to the polymorphism, we can’t predict in advance which
> >> concrete class instance will be sent in each specific case.
> >> 
> >> On the receiving end, I’d expect build() to apply some sort of
> >> hint when deciding which concrete class to instantiate.
> >> original_tagname_ provides that hint, and gives me working code,
> >> but as you said below, it seemed somewhat odd that I was required
> >> to set original_tagname_ in the instance before exporting it; in a
> >> perfect world I’d have expected oadr_20b.py to “know” that hint
> >> already by other means.
> > 
> >> 
> >> Rob
> >> 
> >>> On Dec 13, 2017, at 8:06 PM, Dave Kuhlman <dkuhl...@davekuhlman.org> 
> >>> wrote:
> >>> 
> >>> Rob,
> >>> 
> >>> Wait, I think I have a clue.  Of course, I thought I had a different
> >>> clue 3 hours ago.
> >>> 
> >>> I do not think you should have to use original_tagname_, but I need
> >>> to investigate more.  Thanks for that hint.
> >>> 
> >>> Ignore the rest.  It's just me trying to grope through the problem.
> >>> 
> >>> More tomorrow.
> >>> 
> >>> Dave
> >>> 
> >>> I'm trying to localize the following problem:
> >>> 
> >>>> The XSD uses polymorphism, reflected in the generated code as class
> >>>> hierarchies.
> >>>> 
> >>>> In some cases, exported XML nodes are getting named based on their
> >>>> abstract superclasses:
> >>>> 
> >>>> - streamPayloadBase
> >>>> - payloadBase
> >>>> 
> >>>> instead of based on the concrete subclasses
> >>>> 
> >>>> - oadrReportPayload
> >>>> - PayloadFloat
> >>>> - oadrPayloadResourceStatus
> >>>> 
> >>>> As you can see in oadr_test.py, I can avoid this issue by setting
> >>>> the Python instance’s “original_tagname_”. I don't know, though,
> >>>> whether that's the recommended solution — I couldn’t find
> >>>> documentation about the purpose of original_tagname_. Should I have
> >>>> expected the XML nodes to be named correctly without calling
> >>>> original_tagname_? Is there something else that I should have done
> >>>> to avoid the incorrect names?
> >>> 
> >>> Is this problem occuring in `IntervalType`?  `IntervalType` is
> >>> defined as follows:
> >>> 
> >>>   <xs:complexType name="IntervalType">
> >>>       <xs:sequence>
> >>>           <xs:element ref="xcal:dtstart" minOccurs="0"/>
> >>>           <xs:element ref="xcal:duration" minOccurs="0"/>
> >>>           <xs:element ref="xcal:uid" minOccurs="0"/>
> >>>           <xs:element ref="strm:streamPayloadBase" maxOccurs="unbounded"/>
> >>>       </xs:sequence>
> >>>   </xs:complexType>
> >>> 
> >>> But, as you mention, `streamPayloadBase` is an abstract type.
> >>> So, the above erroneous.  We should not be able to define an
> >>> instance of an abstract type.  After all, how would we know what
> >>> it's concrete type is?  Which subclass is it an instance of?
> >>> 
> >>> It seems to me that in xs:complexType `IntervalType`, each child
> >>> needs to be defined as a concrete (i.e. not an abstract) type.
> >>> 
> >>> So, in oadr_test.py, when you create an instance of the
> >>> `streamPayloadBase` class and add that instance to the instance of
> >>> the `IntervalType`, there is no way for the `IntervalType` to know
> >>> the (concrete) type of the `streamPayloadBase` instance.
> >>> 
> >>> But, wait, you are creating an instance of the
> >>> `oadrReportPayloadType` class, which *is* a concrete type.
> >>> 
> >>> So, our problem is that the `IntervalType` should not be telling
> >>> that instance its name.
> >>> 
> >>> It might be that there is another way around this using xsi:type in
> >>> the XML instance document, but I don't really understand how that is
> >>> supposed to work.
> >>> 
> >>> Or, am I looking at the wrong definition and class?
> >>> 
> >>> I'll keep looking.  I do have a tendency to try to blame others for
> >>> my own problems.
> >>> 
> >>> 
> >>> Dave
> >>> 
> >>> On Tue, Dec 12, 2017 at 12:38:18AM +0000, 
> >>> generateds-users-ow...@lists.sourceforge.net wrote:
> >>>> As list administrator, your authorization is requested for the
> >>>> following mailing list posting:
> >>>> 
> >>>>   List:    generateds-users@lists.sourceforge.net
> >>>>   From:    r...@kisensum.com
> >>>>   Subject: Fwd: original_tagname_, etc.
> >>>>   Reason:  Message body is too big: 2353427 bytes with a limit of 40 KB
> >>>> 
> >>>> At your convenience, visit:
> >>>> 
> >>>>   https://lists.sourceforge.net/lists/admindb/generateds-users
> >>>> 
> >>>> to approve or deny the request.
> >>> 
> >>>> Date: Mon, 11 Dec 2017 16:38:02 -0800
> >>>> From: Rob Calvert <r...@kisensum.com>
> >>>> To: generateds-users@lists.sourceforge.net
> >>>> Subject: Fwd: original_tagname_, etc.
> >>>> X-Mailer: Apple Mail (2.3273)
> >>>> 
> >>>> Dave, I quickly tried out your new 2.29.3 version of generateDS, 
> >>>> wondering whether it might clear up some things I’m currently doing to 
> >>>> work around generated-code issues. It hasn’t changed what I’m seeing, 
> >>>> though, so I’m seeking your advice.
> >>>> 
> >>>> Before describing the current problem, let me thank you for helping my 
> >>>> colleague Bob Barcklay last month. The 2.29.0 version of generateDS 
> >>>> solved some of what we’d been hitting, allowing us to meet a deliverable 
> >>>> deadline. So, on to the current set of issues...
> >>>> 
> >>>> I've implemented an XML protocol that uses the OpenADR v2.0b schema. (It 
> >>>> can be downloaded from here 
> >>>> <http://www.openadr.org/specification-download>; I’d send it as an 
> >>>> attachment, but it’s large and encompasses many files, and SourceForge 
> >>>> doesn’t let me attach a .zip file.) After using generateDS v2.29.3 to 
> >>>> generate the Python file, I’m finding that I need to implement a few 
> >>>> workarounds in order to get working code:
> >>>> 
> >>>> The XSD uses polymorphism, reflected in the generated code as class 
> >>>> hierarchies. In some cases, exported XML nodes are getting named based 
> >>>> on their abstract superclasses (streamPayloadBase, payloadBase) instead 
> >>>> of based on the concrete subclasses (oadrReportPayload, PayloadFloat, 
> >>>> oadrPayloadResourceStatus). As you can see in oadr_test.py, I can avoid 
> >>>> this issue by setting the Python instance’s “original_tagname_”. I don't 
> >>>> know, though, whether that's the recommended solution — I couldn’t find 
> >>>> documentation about the purpose of original_tagname_. Should I have 
> >>>> expected the XML nodes to be named correctly without calling 
> >>>> original_tagname_? Is there something else that I should have done to 
> >>>> avoid the incorrect names?
> >>>> If I export XML using the original, untweaked version of oadr_20b.py, 
> >>>> the export fails because the “intervals” class lacks a “strm" 
> >>>> namespacedef. (You can see this yourself if you switch which oadr import 
> >>>> statement is commented out in oadr_test.py.) 
> >>>> If I export XML using the original, untweaked version of oadr_20b.py, 
> >>>> the namespace of PayloadFloat is “oadr", which is incorrect — it should 
> >>>> be "ei”.
> >>>> 
> >>>> If you’re able to shed any light on these issues, I’d greatly appreciate 
> >>>> it.
> >>>> 
> >>>> Rob Calvert
> >>>> (510) 759-1838
> >>>> www.kisensum.com <http://www.kisensum.com/>
> >>>> 
> >>>> Kisensum | 344 Thomas Berkley Way #260 | Oakland, CA, 94612
> >>>> 
> >>>> Attachments:
> >>>> oadr_20b_v2_29_3.py (original generateDS output)
> >>>> oadr_20b.py (tweaked version of generateDS output containing some 
> >>>> workarounds)
> >>>> oadr_test.py (test code)
> >>>> 
> >>>> 
> >>>> 
> >>>>> Dave, I quickly tried out your new 2.29.3 version of generateDS, 
> >>>>> wondering whether it might clear up some things I’m currently doing to 
> >>>>> work around generated-code issues. It hasn’t changed what I’m seeing, 
> >>>>> though, so it’s time for me to ask your advice.
> >>>>> 
> >>>>> Before describing the current issues, let me thank you for helping my 
> >>>>> colleague Bob Barcklay last month. The 2.29.0 version of generateDS 
> >>>>> solved some of the problems we’d been hitting, allowing us to meet a 
> >>>>> deliverable deadline. So, on to the current set of issues...
> >>>>> 
> >>>>> I've implemented an XML protocol that uses the OpenADR v2.0b schema 
> >>>>> (the schema can be downloaded from here (I’d send it to you as an 
> >>>>> attachment, but SourceForge doesn't let me attach a .zip, and the 
> >>>>> schema is large and encompasses many files). After using generateDS 
> >>>>> v2.29.3 to generate a Python file for that schema, I’m finding that I 
> >>>>> need to implement a few workarounds in order to get working code:
> >>>>> 
> >>>>> The XSD uses polymorphism, reflected in the generated code as class 
> >>>>> hierarchies. In some cases, exported XML nodes are getting named based 
> >>>>> on their abstract superclasses (streamPayloadBase, payloadBase) instead 
> >>>>> of based on the concrete subclasses (oadrReportPayload, PayloadFloat, 
> >>>>> oadrPayloadResourceStatus). As you can see in oadr_test.py, I can avoid 
> >>>>> this issue by setting the Python instance’s “original_tagname_”. I 
> >>>>> don't know, though, whether that's the recommended solution — I 
> >>>>> couldn’t find documentation about the purpose of original_tagname_. 
> >>>>> Should I have expected the XML nodes to be named correctly without 
> >>>>> calling original_tagname_? Is there something else that I should have 
> >>>>> done to avoid the incorrect names?
> >>>>> If I export XML using the original, untweaked version of oadr_20b.py, 
> >>>>> the export fails because the “intervals” class lacks a “strm" 
> >>>>> namespacedef. (You can see this yourself if you switch which oadr 
> >>>>> import statement is commented out in oadr_test.py.) 
> >>>>> If I export XML using the original, untweaked version of oadr_20b.py, 
> >>>>> the namespace of PayloadFloatType is "oadr", which is incorrect — it 
> >>>>> should be "ei”.
> >>>>> 
> >>>>> If you’re able to shed any light on these issues, I’d greatly 
> >>>>> appreciate it.
> >>>>> 
> >>>>> Rob Calvert
> >>>>> (510) 759-1838
> >>>>> www.kisensum.com <http://www.kisensum.com/>
> >>>>> 
> >>>>> Kisensum | 344 Thomas Berkley Way #260 | Oakland, CA, 94612
> >>>>> 
> >>>>> Attachments:
> >>>>> oadr_20b_v2_29_3.py (original generateDS output)
> >>>>> oadr_20b.py (tweaked version of generateDS output containing some 
> >>>>> workarounds)
> >>>>> oadr_test.py (test code)
> >>>>> 
> >>>>> 
> >>>>> 
> >>>>> 
> >>>> 
> >>> 
> >>>> Date: Tue, 12 Dec 2017 00:38:18 +0000
> >>>> From: generateds-users-requ...@lists.sourceforge.net
> >>>> Subject: confirm 24bf5689ce6295e0d6d499e87b69e3433e2a9d93
> >>>> 
> >>>> If you reply to this message, keeping the Subject: header intact,
> >>>> Mailman will discard the held message.  Do this if the message is
> >>>> spam.  If you reply to this message and include an Approved: header
> >>>> with the list password in it, the message will be approved for posting
> >>>> to the list.  The Approved: header can also appear in the first line
> >>>> of the body of the reply.
> >>> 
> >>> 
> >>> 
> >>> 
> >>> -- 
> >>> 
> >>> Dave Kuhlman
> >>> http://www.davekuhlman.org
> >> 
> > 
> > -- 
> > 
> > Dave Kuhlman
> > http://www.davekuhlman.org
> 

-- 

Dave Kuhlman
http://www.davekuhlman.org

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
generateds-users mailing list
generateds-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/generateds-users

Reply via email to