Skip to main content
 首页 » 编程设计

python之使用 xml.dom.minidom 时在 xml 中转义 '' 和 '>'

2025年05月04日10txw1958

我在使用 xml.dom.minidom 转义 xml 文件中的“<”和“>”时卡住了。 我试图获取 unicode 十六进制值并改用它
http://slayeroffice.com/tools/unicode_lookup/

尝试使用标准的“<”和“>”,但仍然没有成功。

from xml.dom.minidom import Document 
doc = Document() 
e = doc.createElement("abc") 
s1 = '<hello>bhaskar</hello>' 
text = doc.createTextNode(s1) 
e.appendChild(text) 
 
e.toxml() 
'<abc>&lt;hello&gt;bhaskar&lt;/hello&gt;</abc>' 

与 writexml() 相同的结果 还尝试在 toxml() writexml() 调用中指定编码“UTF-8”、“utf-8”、“utf”,但结果相同。

from xml.dom.minidom import Document 
doc = Document() 
e = doc.createElement("abc") 
s1 = u'&lt;hello&gt;bhaskar&lt;/hello&gt;' 
text = doc.createTextNode(s1) 
e.appendChild(text) 
 
e.toxml() 
u'<abc>&amp;lt;hello&amp;gt;bhaskar&amp;lt;/hello&amp;gt;</abc>' 

尝试了其他方法,但结果相同。 我唯一可以解决的方法是覆盖作者

import xml.dom.minidom as md 
# XXX Hack to handle '<' and '>' 
def wd(writer, data): 
    data = data.replace("&lt;", "<").replace("&gt;", ">") 
    writer.write(data) 
 
md._write_data = wd 

编辑 - 这是代码。

    import xml.dom.minidom as md 
    doc = md.Document() 
 
    entity_descr = doc.createElement("EntityDescriptor") 
    doc.appendChild(entity_descr) 
    entity_descr.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata') 
    entity_descr.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion') 
    entity_descr.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#') 
    # Get the entity_id from saml20_idp_settings 
    entity_descr.setAttribute('entityID', self.group['entity_id']) 
 
    idpssodescr = doc.createElement('IDPSSODescriptor') 
    idpssodescr.setAttribute('WantAuthnRequestsSigned', 'true') 
    idpssodescr.setAttribute('protocolSupportEnumeration',  
    'urn:oasis:names:tc:SAML:2.0:protocol') 
    entity_descr.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) 
 
 
    # check this part  
 
    s = "this is a cert  blah blah" 
    x509cert = doc.createElement('ds:X509Certificate') 
    cert = doc.createTextNode(s) 
    x509cert.appendChild(cert) 
    x509data.appendChild(x509cert) 
 
    sso = doc.createElement('SingleSignOnService') 
    sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect') 
 
    sso.setAttribute('Location', 'http://googleapps/singleSignOn') 
    idpssodescr.appendChild(sso) 
 
    # Write the metadata file. 
    fobj = open('metadata.xml', 'w') 
    doc.writexml(fobj, "   ", "", "\n", "UTF-8") 
    fobj.close() 

这产生

   <?xml version="1.0" encoding="UTF-8"?> 
   <EntityDescriptor entityID="skar" 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> 
    this is a cert  blah blah 
   </ds:X509Certificate> 
   </ds:X509Data> 
   </ds:KeyInfo> 
   </KeyDescriptor> 
   <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"  
   Location="http:///singleSignOn"/> 
   </IDPSSODescriptor> 
   </EntityDescriptor> 

注意“This is a cert”单独出现 我为此伤脑筋,但结果相同。

请您参考如下方法:

这不是错误,这是一个功能。要插入实际的 XML,请改为插入 DOM 对象。 XML 标记内的文本需要进行实体转义才能成为有效的 XML。

from xml.dom.minidom import Document 
doc = Document() 
e = doc.createElement("abc") 
eh = doc.createElement("hello") 
s1 = 'bhaskar' 
text = doc.createTextNode(s1) 
 
eh.appendChild(text) 
e.appendChild(eh) 
 
e.toxml() 

编辑: 我不知道 Python 的 API 是什么样的,但它看起来与 C# 的 API 非常相似,因此您可以执行类似 e.innerXml = s1 的操作。做你想做的事……但这可能很糟糕。更好的做法是解析它并 appendChild

编辑 2: 我只是在本地通过 Python 运行了这个程序,你这边肯定有问题,而不是在库中。 确保您的字符串的开头没有任何换行符或空格。作为引用,我使用的测试代码是:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)  
[GCC 4.3.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from xml.dom.minidom import Document 
>>> cert = "---- START CERTIFICATE ----\n   Hello world\n---- END CERTIFICATE ---" 
>>> doc = Document() 
>>> e = doc.createElement("cert") 
>>> certEl = doc.createTextNode(cert) 
>>> e.appendChild(certEl) 
<DOM Text node "'---- START'..."> 
>>> print e.toxml() 
<cert>---- START CERTIFICATE ---- 
   Hello world 
---- END CERTIFICATE ---</cert> 
>>>  

编辑 3: 最后的编辑。问题出在你的 writexml 称呼。只需使用以下方法即可解决此问题:

doc.writexml(fobj) 
# or 
doc.writexml(fobj, "", "  ", "") 

不幸的是,您似乎无法使用 newline参数来获得 pretty-print ......似乎 Python 库(或至少 minidom)编写得相当糟糕,并且会在打印它们时修改 TextNode。与其说是一个糟糕的实现,不如说是一个天真的实现。真的很遗憾...