【问题标题】:Parsing soap/XML response in Python在 Python 中解析soap/XML 响应
【发布时间】:2017-06-14 10:18:59
【问题描述】:

我正在尝试使用 python 解析下面的 xml。我不明白这是哪种类型的 xml,因为我从未处理过这种类型的 xml。我只是从 Microsoft 的 api 响应中得到它。

现在我的问题是如何在我的 python 代码中解析和获取BinarySecurityToken 的值。

这个问题我参考Parse XML SOAP response with Python

但是看起来这也有一些 xmlns 来获取文本。但是在我的 xml 中我看不到任何附近的 xmlns 值,通过我可以获得值。

请告诉我如何使用 python 从下面的 xml 中获取特定文件的值。

<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing">
  <S:Header>
    <wsa:Action xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Action" S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</wsa:Action>
    <wsa:To xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="To" S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
    <wsse:Security S:mustUnderstand="1">
      <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TS">
        <wsu:Created>2017-06-12T10:23:01Z</wsu:Created>
        <wsu:Expires>2017-06-12T10:28:01Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </S:Header>
  <S:Body>
    <wst:RequestSecurityTokenResponse xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
      <wst:TokenType>urn:passport:compact</wst:TokenType>
      <wsp:AppliesTo xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:EndpointReference>
          <wsa:Address>https://something.something.something.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wst:Lifetime>
        <wsu:Created>2017-06-12T10:23:01Z</wsu:Created>
        <wsu:Expires>2017-06-13T10:23:01Z</wsu:Expires>
      </wst:Lifetime>
      <wst:RequestedSecurityToken>
        <wsse:BinarySecurityToken Id="Compact0">my token</wsse:BinarySecurityToken>
      </wst:RequestedSecurityToken>
      <wst:RequestedAttachedReference>
        <wsse:SecurityTokenReference>
          <wsse:Reference URI="wwwww=">
          </wsse:Reference>
        </wsse:SecurityTokenReference>
      </wst:RequestedAttachedReference>
      <wst:RequestedUnattachedReference>
        <wsse:SecurityTokenReference>
          <wsse:Reference URI="swsw=">
          </wsse:Reference>
        </wsse:SecurityTokenReference>
      </wst:RequestedUnattachedReference>
    </wst:RequestSecurityTokenResponse>
  </S:Body>
</S:Envelope>

【问题讨论】:

    标签: python xml parsing soap elementtree


    【解决方案1】:

    这个声明是根元素开始标签的一部分:

    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    

    表示带有wsse前缀的元素(如BinarySecurityToken)在http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd命名空间中。

    解决方案与链接问题的答案基本相同。这只是另一个命名空间:

    import xml.etree.ElementTree as ET
    
    tree = ET.parse('soap.xml')    
    print tree.find('.//{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken').text
    

    这是另一种方法:

    import xml.etree.ElementTree as ET
    
    ns = {"wsse": "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"}
    tree = ET.parse('soap.xml') 
    print tree.find('.//wsse:BinarySecurityToken', ns).text
    

    两种情况下的输出都是my token

    https://docs.python.org/2.7/library/xml.etree.elementtree.html#parsing-xml-with-namespaces

    【讨论】:

      【解决方案2】:

      创建命名空间字典帮助了我。感谢 @mzjn 链接那篇文章。

      在我的 SOAP 响应中,我发现我不得不使用元素的完整路径来提取文本。

      例如,我正在使用 FEDEX API,我需要找到的一个元素是 TrackDetails。我最初的.find() 看起来像.find('{http://fedex.com/ws/track/v16}TrackDetails')

      我可以将其简化为以下内容:

      ns = {'TrackDetails': 'http://fedex.com/ws/track/v16'}
      tree.find('TrackDetails:TrackDetails',ns)
      

      您会看到两次 TrackDetails,因为我在 dict 中命名了键 TrackDetails,但您可以随意命名。只是帮助我记住了我在项目中所做的工作,但: 之后的 TrackDetails 是我需要的 SOAP 响应中的实际元素。

      希望这对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 2016-09-03
        • 1970-01-01
        • 1970-01-01
        • 2016-05-05
        • 2020-02-07
        • 1970-01-01
        相关资源
        最近更新 更多