如何通过在XML上用SOAP替换值来发送XML请求?

时间:2018-06-17 16:54:02

标签: python xml django soap python-requests

我的模板目录中有一个XML文件,这个XML文件有一些占位符。我需要使用数据库中的值和其他值的计算(基于用户输入)填充这些占位符,然后将其发送到将处理此XML并返回XML响应的URL。

这就是我的XML文件的外观:

my_file.xml

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://some_url.api.com" xmlns:web1="http://another_url.api.com">
<soapenv:Header>
    <web:AuthenticationToken>
        <web:licenseKey> string </web:licenseKey>
        <web:password> string </web:password>
        <web:username> string </web:username>
    </web:AuthenticationToken>
</soapenv:Header>
<soapenv:Body>
    <web:Shipping>
        <web:ShipRequest>
            <web1:dtnCtry> string </web1:dtnCtry>
            <web1:dtnZC> string </web1:dtnZC>
            <web1:details>
            <!--Zero or more repetitions:-->
                <web1:ShipRequestDetail>
                <web1:class> string </web1:class>
                <web1:wt> string </web1:wt>
                </web1:ShipRequestDetail>
            </web1:details>
            <web1:orgCtry> string </web1:orgCtry>
            <web1:orgZC> string </web1:orgZC>
            <web1:shipDateCCYYMMDD> string </web1:shipDateCCYYMMDD>
            <web1:shipID> string </web1:shipID>
            <web1:tarName> string </web1:tarName>
        </web:ShipRequest>
    </web:Shipping>
</soapenv:Body>

每个string值都必须替换为实际的数据库值。我该如何处理这个过程?

我在SO中检查了多个论坛,网站和多个问题,每个人都推荐了不同的方法。作为一个新手,我很难选择一个,这是非常压倒性的。

有人可以从头开始解释一个过程吗?谢谢!

1 个答案:

答案 0 :(得分:0)

考虑使用Python lxml

将参数传递到XSLT脚本中

XSLT (另存为.xsl文件)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                              xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                              xmlns:web="http://some_url.api.com" 
                              xmlns:web1="http://another_url.api.com">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8"/>
    <xsl:strip-space elements="*"/>

    <!-- XSLT PARMS (TO RECEIVE PYTHON VALUES) -->
    <xsl:param name="licenseKey_param"/>
    <xsl:param name="password_param"/>
    <xsl:param name="username_param"/>
    <xsl:param name="dtnCtry_param"/>
    <xsl:param name="dtnZC_param"/>
    <xsl:param name="class_param"/>
    <xsl:param name="wt_param"/>
    <xsl:param name="orgCtry_param"/>
    <xsl:param name="orgZC_param"/>
    <xsl:param name="shipDateCCYYMMDD_param"/>
    <xsl:param name="shipID_param"/>
    <xsl:param name="tarName_param"/>

    <xsl:template match="/*">
     <xsl:copy>
      <soapenv:Header>
        <web:AuthenticationToken>
          <web:licenseKey><xsl:value-of select="$licenseKey_param"/></web:licenseKey>
          <web:password><xsl:value-of select="$password_param"/></web:password>
          <web:username><xsl:value-of select="$username_param"/></web:username>
        </web:AuthenticationToken>
      </soapenv:Header>
      <soapenv:Body>
        <web:Shipping>
          <web:ShipRequest>
        <web1:dtnCtry><xsl:value-of select="$dtnCtry_param"/></web1:dtnCtry>
        <web1:dtnZC><xsl:value-of select="$dtnZC_param"/></web1:dtnZC>
        <web1:details>
          <xsl:comment>  Zero or more repetitions:  </xsl:comment>
          <web1:ShipRequestDetail>
            <web1:class><xsl:value-of select="$class_param"/></web1:class>
            <web1:wt><xsl:value-of select="$wt_param"/></web1:wt>
          </web1:ShipRequestDetail>
        </web1:details>
        <web1:orgCtry><xsl:value-of select="$orgCtry_param"/></web1:orgCtry>
        <web1:orgZC><xsl:value-of select="$orgZC_param"/></web1:orgZC>
        <web1:shipDateCCYYMMDD><xsl:value-of select="$shipDateCCYYMMDD_param"/></web1:shipDateCCYYMMDD>
        <web1:shipID><xsl:value-of select="$shipID_param"/></web1:shipID>
        <web1:tarName><xsl:value-of select="$tarName_param"/></web1:tarName>
          </web:ShipRequest>
        </web:Shipping>
      </soapenv:Body>
     </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Python (将strparam()中的字符串文字调整为数据库值和计算)

import lxml.etree as et

# LOAD XML AND XSL
doc = et.parse('my_file.xml')
xsl = et.parse('my_script.xsl')

# CONFIGURE TRANSFORMER
transform = et.XSLT(xsl)    

# RUN TRANSFORMATION WITH PARAMS
result = transform(doc, 
                   licenseKey_param = et.XSLT.strparam('123123'),
                   password_param = et.XSLT.strparam('password'),
                   username_param = et.XSLT.strparam('Di437'),
                   dtnCtry_param = et.XSLT.strparam('Python Country'),
                   dtnZC_param = et.XSLT.strparam('Django ZC'),
                   class_param = et.XSLT.strparam('my class'),
                   wt_param = et.XSLT.strparam('my wt'),
                   orgCtry_param = et.XSLT.strparam('XML Country'),
                   orgZC_param = et.XSLT.strparam('Soap ZC'),
                   shipDateCCYYMMDD_param = et.XSLT.strparam('2018-06-17 12:00'),
                   shipID_param = et.XSLT.strparam('888999'),
                   tarName_param = et.XSLT.strparam('stackoverflow'))

# PRINT RESULT
print(result)  

# SAVE TO FILE
with open('output.xml', 'wb') as f:
   f.write(result)

<强>输出

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://some_url.api.com" xmlns:web1="http://another_url.api.com">
  <soapenv:Header>
    <web:AuthenticationToken>
      <web:licenseKey>123123</web:licenseKey>
      <web:password>password</web:password>
      <web:username>Di437</web:username>
    </web:AuthenticationToken>
  </soapenv:Header>
  <soapenv:Body>
    <web:Shipping>
      <web:ShipRequest>
        <web1:dtnCtry>Python Country</web1:dtnCtry>
        <web1:dtnZC>Django ZC</web1:dtnZC>
        <web1:details>
          <!--  Zero or more repetitions:  -->
          <web1:ShipRequestDetail>
            <web1:class>my class</web1:class>
            <web1:wt>my wt</web1:wt>
          </web1:ShipRequestDetail>
        </web1:details>
        <web1:orgCtry>XML Country</web1:orgCtry>
        <web1:orgZC>Soap ZC</web1:orgZC>
        <web1:shipDateCCYYMMDD>2018-06-17 12:00</web1:shipDateCCYYMMDD>
        <web1:shipID>888999</web1:shipID>
        <web1:tarName>stackoverflow</web1:tarName>
      </web:ShipRequest>
    </web:Shipping>
  </soapenv:Body>
</soapenv:Envelope>