使用python编写XML文件

2024-10-02 08:20:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须使用python标准模块编写一个xml文件(不使用elementtree、lxml等),元数据是SAML标识提供程序元数据,其格式为-

<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    entityID="http://wsa.saas.com">
<IDPSSODescriptor>
<KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:X509Data><ds:X509Certificate>-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR
LlTxKnCrWAXftSm1rNtewTsF
-----END CERTIFICATE-----
</ds:X509Certificate></ds:X509Data>
    </ds:KeyInfo>
  </KeyDescriptor>

  <SingleSignOnService
    Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    Location="http://idp5/singleSignOn" />
</IDPSSODescriptor>
</EntityDescriptor>

我目前的代码是这样做的-

^{pr2}$

我对证书部分有点困惑。原稿是<ds:X509Certificate>-----BEGIN CERTIFICATE---.....</ds:X509Certificate> 我的是:

 <ds:X509Certificate>
    This is the cert
 </ds:X509Certificate>

对不起,我对XML没有太多的经验。 代码是否适合预期的任务。在

谢谢。在


Tags: 数据httpnameswwwdssamlxmlcertificate
3条回答

嗯?你的问题是什么?在这两行中:

>>> ptext = doc.createTextNode("This is a test!")
>>> x509cert.appendChild(ptext)

实际上,您正在创建一个文本节点作为节点"<ds:X509Certificate>"的子节点 . 文本节点的内容是“这是一个测试!”。如果要插入其他内容作为文本内容,则必须使用适当的参数调用.createTextNode。在

编辑(考虑操作员的评论): 不,它不是文本内容。在XML中,每件事都是一个节点。您认为的“标签之间的文本”实际上是一个文本节点。在

只是为了存档,我以前的代码缺少了一个小的更改,这就是为什么证书被拒绝的原因。在

from xml.dom.minidom import Document
doc = Document()
entity_descriptor = doc.createElement("EntityDescriptor")
doc.appendChild(entity_descriptor)
entity_descriptor.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata')
entity_descriptor.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion')
entity_descriptor.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#')
entity_descriptor.setAttribute('entityID', 'http://wsa.saas.com')
idpssodescr = doc.createElement('IDPSSODescriptor')
idpssodescr.setAttribute('WantAuthnRequestsSigned', 'true')
idpssodescr.setAttribute('protocolSupportEnumeration',   
'urn:oasis:names:tc:SAML:2.0:protocol')
entity_descriptor.appendChild(idpssodescr)
keydescr = doc.createElement('KeyDescriptor')
keydescr.setAttribute('use', 'signing')
idpssodescr.appendChild(keydescr)
keyinfo = doc.createElement('ds:KeyInfo')
keyinfo.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#')
keydescr.appendChild(keyinfo)
x509data = doc.createElement('ds:X509Data')
keyinfo.appendChild(x509data)
x509cert = doc.createElement('ds:X509Certificate')

# Read the certificate from some file.
fp = file('idp.crt.pem', 'r')
s = ''
for i in fp.readlines():
    s+=''.join(i)


ptext = doc.createTextNode(s)
x509cert.appendChild(ptext)
x509data.appendChild(x509cert)
sso = doc.createElement('SingleSignOnService')
sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect')
sso.setAttribute('Location', 'http://idp5/singleSignOn')
idpssodescr.appendChild(sso)

print doc.toprettyxml(indent="  ")
<?xml version="1.0" ?>
<EntityDescriptor entityID="http://wsa.saas.com"  
xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09  
/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<IDPSSODescriptor WantAuthnRequestsSigned="true"    
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
  <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:X509Data>
      <ds:X509Certificate>
          -BEGIN CERTIFICATE  -
MIICfTCCAeagAwIBAgIJAPEn4h3J3p2dMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
BAYTAmFhMQswCQYDVQQKEwJhYTELMAkGA1UECxMCYWExCzAJBgNVBAMTAmFhMB4X
DTA5MTAxOTA4NTI1M1oXDTEwMTAxOTA4NTI1M1owNDELMAkGA1UEBhMCYWExCzAJ
BgNVBAoTAmFhMQswCQYDVQQLEwJhYTELMAkGA1UEAxMCYWEwgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBAMerInhZF/l0O0jmiD8M1lSSpHjFcT0peiwqWq+LZ8Ay
b6mcpnHdFVmHQaGtUt+6i+0NqKDppxnaVW4vOdYD64OlmSVrG+WzkYMAmE/0EzJN
A5pEA5ZK1w6MGo+IQLjrPDmm/qV6XrkARR2THjA2xKE8/L7s+VEJj/d+/CC8V7vP
AgMBAAGjgZYwgZMwHQYDVR0OBBYEFOHoipN0T0TNs1IwFkmTwLDtsV0gMGQGA1Ud
IwRdMFuAFOHoipN0T0TNs1IwFkmTwLDtsV0goTikNjA0MQswCQYDVQQGEwJhYTEL
MAkGA1UEChMCYWExCzAJBgNVBAsTAmFhMQswCQYDVQQDEwJhYYIJAPEn4h3J3p2d
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEANTQgpYm+OBZTTYbLkyBH
MQ9QygwgNWOQJ9hEbT0xpiL8xHXBTQdHJkMXD/PWzs1AyZShXsUwcKBaKgxyIsQj
a36poKPyfAYbfsg8xLyijMVXbsW7OlKN9FjapaZTnEvHfsMO8ITAad4a7RVWAYQ8
ucT7nO9OPFjOv8dwGsF5RVM=
  -END CERTIFICATE  -

      </ds:X509Certificate>
    </ds:X509Data>
  </ds:KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"   
Location="http://idp5/singleSignOn"/>
</IDPSSODescriptor>
</EntityDescriptor>

x = open('metadata.xml', 'w')
doc.writexml(x, "   ", "", "\n", "UTF-8")
x.close()

Yattag对此可能很有意思

from yattag import Doc, indent

doc, tag, text = Doc().tagtext()

doc.asis('<?xml version="1.0"?>')
with tag('EntityDescriptor',
        ("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion"), 
        ("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#"),
        entityID = "http://wsa.saas.com",
        xmlns = "urn:oasis:names:tc:SAML:2.0:metadata"):
    with tag('IDPSSODescriptor'):
        with tag('KeyDescriptor', use='signing'):
            with tag('ds:KeyInfo', 
                    ("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")):
                with tag('ds:X509Data'):
                    with tag('ds:X509Certificate'):
                        text(
"""  -BEGIN CERTIFICATE  -
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR
LlTxKnCrWAXftSm1rNtewTsF
  -END CERTIFICATE  -
""")
    with tag('SingleSignOnService',
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
        Location="http://idp5/singleSignOn"
    ):
        pass


result = indent(
    doc.getvalue(),
    indentation = ' '*4,
    newline = '\r\n'
)

print(result)

你会得到:

^{pr2}$

相关问题 更多 >

    热门问题