pythonxmlsoapsuds

How to add an element to a structure in SUDS (python)?


I create the structure AccountAssignment

client = suds.client.Client(url)
accountAssignment = client.factory.create('AccountAssignment')
print accountAssignment 

I get the following result:

(AccountAssignment){
   Key = None
   AccountNo = None
   TaxCode = None
   Debit = None
   Credit = None
   Turnover = None
   Text = None
   FCDebit = None
   FCCredit = None
   FCTurnover = None
   SummaryAccount = None
   Balance = None
   BankNo = None
   BanksortingCode = None
   BankAccountNo = None
   DepositFormNo = None
   DepositFormDate = None
   ChequeNumber = None
   ExpiryDate = None
   GroupMovementType = None
   AssociatedCompany = None
   Comment1 = None
   Comment2 = None
   Comment3 = None
   AdditionalDate1 = None
   AdditionalDate2 = None
 }

Then I am able to set the desired values and send that structure to the appropriate method. The problem is, that there are two elements missing in the structure. The AccountAssignment should look like this:

(AccountAssignment){
   Key = None
   AccountNo = None
   TaxCode = None
   Debit = None
   Credit = None
   Turnover = None
   Text = None
   FCDebit = None
   FCCredit = None
   FCTurnover = None
   SummaryAccount = None
   Balance = None
   BankNo = None
   BanksortingCode = None
   BankAccountNo = None
   DepositFormNo = None
   DepositFormDate = None
   ChequeNumber = None
   ExpiryDate = None
   GroupMovementType = None
   AssociatedCompany = None
   Comment1 = None
   Comment2 = None
   Comment3 = None
   AdditionalDate1 = None
   AdditionalDate2 = None
   DebitSpecified = None      ** how to add this?
   CreditSpecified = None     ** how to add this?
 }

I tried to add the missing elements with a MessagePlugin and its method marshalled(). The result is, that the elements are added just before sending, which is too late. I need to set values to the two missing elements, so the elements have to be present before I call the sending-method. I also experimented with InitPlugin and DocumentPlugin, with no luck. Any ideas?


Solution

  • Solution:

    I solved the issue by using a DocumentPlugin and implementing its method parsed(). Since there seems nobody interessted anyway, I just provide some code but do not comment it any further. I lost enough time on this.

    class AccountAssignmentPlugin(suds.plugin.DocumentPlugin):
        """Plugin to add element to AccountAssignment that is not defined in WSDL."""
        def __init__(self, *args):
            self.args = args
    
        def parsed(self, context):
            # See documentation at http://jortel.fedorapeople.org/suds/doc/suds.sax.element.Element-class.html
            # and http://jortel.fedorapeople.org/suds/doc/suds.sax.attribute.Attribute-class.html
            complexTypes = context.document.getRoot().getChild('types').getChild('schema').getChildren('complexType')
            # Get the complex type with attribute 'name' == 'AccountAssignment'.
            for ct in complexTypes:
                if ct.get('name') == 'AccountAssignment':
                    accountAssignment = ct
    
            # Get the elements of the AccountAssignment that are used as attributes of the AttributeAssignment object.
            sequenceElements = accountAssignment.getChild('complexContent').getChild('extension').getChild('sequence')
    
            for key in self.args:
                # Create new element (node)
                e = suds.sax.element.Element('element')
                e.setPrefix('s')
    
                # Add attributes
                a = suds.sax.attribute.Attribute('maxOccurs')
                a.setValue(1)
                e.append(a)
    
                a = suds.sax.attribute.Attribute('type')
                a.setValue('s:boolean')
                e.append(a)
    
                a = suds.sax.attribute.Attribute('name')
                a.setValue(key)
                e.append(a)
    
                a = suds.sax.attribute.Attribute('minOccurs')
                a.setValue(0)
                e.append(a)
    
                sequenceElements.append(e)
    
              
    def transactionService(self):
        module_name = 'WS3Trans'
        service_name = 'TransactionService'
        service_url = '%s/%s/%s.asmx?WSDL' %(self.webservice_url, module_name, service_name)
        client = suds.client.Client(service_url, plugins=[AccountAssignmentPlugin('DebitSpecified', 'CreditSpecified')])
        return client