如何在SUDS(Python)中向结构添加元素?

11 投票
1 回答
2285 浏览
提问于 2025-04-18 09:24

我创建了一个叫做AccountAssignment的结构。

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

我得到了以下结果:

(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
 }

然后我可以设置想要的值,并把这个结构发送到合适的方法。不过,问题是,这个结构里缺少两个元素。AccountAssignment应该是这样的:

(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?
 }

我尝试用一个叫MessagePlugin的工具和它的marshalled()方法来添加缺失的元素。结果是,这些元素是在发送之前才被添加的,这样就太晚了。我需要在调用发送方法之前就把这两个缺失的元素的值设置好,所以这些元素必须在我调用发送方法之前就存在。我还试过InitPlugin和DocumentPlugin,但都没有成功。有没有什么好的建议?

1 个回答

0

解决方案:

我通过使用一个叫做DocumentPlugin的工具,并实现它的parsed()方法来解决这个问题。看起来也没有人对此感兴趣,所以我就提供一些代码,不再多做解释。我在这上面浪费了足够的时间。

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

撰写回答