Menu

Bizarre behaviour with setDefaultNamespace

Help
rob linton
2015-05-14
2015-05-15
  • rob linton

    rob linton - 2015-05-14

    Hi,

    I'm experiencing some bizarre behaviour which I'm sure is due to my very partial understanding of XML.

    I'm creating XML documents via bindings created with pyxb, This is all working as expected. Sadly, the target software (third-party binary, no chance at changing it) doesn't appear to support namespaces.

    So I thought I would specify a default namespace to placate the troublesome software.

    This is what I do:

    bds = BindingDOMSupport()
    bds.setDefaultNamespace(pybxbinding.Namespace)

    Create my objects as normal.

    myobjects.toxml('utf-8', bds=bds, element_name='rootelement')

    Now the resulting XML has the same elements multiple times and the whole thing is wrapped in another tag which appears to come from nowhere.

    Am I misunderstanding how setDefaultNamespace works? Have I fallen into a common gotcha?

    Many thanks for any insight.

     
  • rob linton

    rob linton - 2015-05-14

    The enormous "Create my objects as normal" was meant to be preceded with a hash... aka a comment...

     
  • Peter A. Bigot

    Peter A. Bigot - 2015-05-14

    Question requires clarification. Please read this and other sections on that page for context.

    The only effect of setting the default namespace when generating DOM or XML text is to add a default namespace declaration to the document root that eliminates the need to use namespace prefixes on element tags and attribute ids that belong to that namespace:

    <foo xmlns="urn:mynamespace"><subfoo/></foo>
    

    versus:

    <ns:foo xmlns:ns="urn:mynamespace"><ns:subfoo/></ns:foo>
    

    What is the target namespace of your schema? If it is absent, you should not need to do anything. If it is not absent, you have a problem because valid documents require the namespace. If the downstream processor doesn't recognize them, you'll need to assign a default namespace (to eliminate the namespace prefixes) then remove the namespace declaration before transmitting the document. The snippet you provided looks like the right way to do that.

    If this doesn't solve your problem, please provide a reduced schema and short example to reproduce what you're seeing, and describe what you want to see instead.

    (NB: Precede displayed code with four spaces to quote it.)

     
  • rob linton

    rob linton - 2015-05-14

    As I was trying to build a better example, I found my problem. Each time I call toxml with the same BindingDOMSupport object, the output from the previous calls is included in the current output.

    trtcx.toxml('utf-8', bds=bds, element_name='TrainingCenterDatabase')
    <?xml version="1.0" encoding="UTF-8"?>
    <TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Sport="Other">
       <Name>Standard 1.5 Mi</Name>
       <Step xsi:type="Step_t">
          <StepId>1</StepId>
          <Name>run</Name>
          <Duration xsi:type="Distance_t">
             <Meters>2414</Meters>
          </Duration>
          <Intensity>Active</Intensity>
          <Target xsi:type="None_t" />
       </Step>
       <Notes />
    </TrainingCenterDatabase>
    

    That's good, second time:

    trtcx.toxml('utf-8', bds=bds, element_name='TrainingCenterDatabase')
    
    <?xml version="1.0" encoding="UTF-8"?>
    <TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Sport="Other">
       <Name>Standard 1.5 Mi</Name>
       <Step xsi:type="Step_t">
          <StepId>1</StepId>
          <Name>run</Name>
          <Duration xsi:type="Distance_t">
             <Meters>2414</Meters>
          </Duration>
          <Intensity>Active</Intensity>
          <Target xsi:type="None_t" />
       </Step>
       <Notes />
       <TrainingCenterDatabase Sport="Other">
          <Name>Standard 1.5 Mi</Name>
          <Step xsi:type="Step_t">
             <StepId>1</StepId>
             <Name>run</Name>
             <Duration xsi:type="Distance_t">
                <Meters>2414</Meters>
             </Duration>
             <Intensity>Active</Intensity>
             <Target xsi:type="None_t" />
          </Step>
          <Notes />
       </TrainingCenterDatabase>
    </TrainingCenterDatabase>
    

    It's printed twice! What should I be doing to prevent this? Should I create a fresh bds each time or is there a way to re-use it?

    Thanks for looking at this.

     
  • Peter A. Bigot

    Peter A. Bigot - 2015-05-14

    There is a reset method you can use. From the description it would probably suit your case as it does not change the default namespace.

     
  • rob linton

    rob linton - 2015-05-15

    Great. I was treating it as simply a config object and it clearly does more than that.

    Thanks for helping me through this!

     

Log in to post a comment.