[英]Escaping '<' and '>' in xml when using xml.dom.minidom
使用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><hello>bhaskar</hello></abc>'
與writexml()的結果相同也可以通過在toxml()writexml()調用中指定編碼'UTF-8','utf-8','utf'來嘗試,但結果相同。
from xml.dom.minidom import Document
doc = Document()
e = doc.createElement("abc")
s1 = u'<hello>bhaskar</hello>'
text = doc.createTextNode(s1)
e.appendChild(text)
e.toxml()
u'<abc>&lt;hello&gt;bhaskar&lt;/hello&gt;</abc>'
嘗試了其他方法,但結果相同。 我可以解決的唯一方法是重寫作者
import xml.dom.minidom as md
# XXX Hack to handle '<' and '>'
def wd(writer, data):
data = data.replace("<", "<").replace(">", ">")
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>
請注意,“這是證書”是單獨發出的,雖然我為此感到頭疼,但結果卻相同。
這不是錯誤,而是功能。 要插入實際的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#的非常相似,因此您可以執行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
參數進行漂亮的打印...似乎Python庫(或至少minidom
)編寫得很差,並且會在打印它們時修改TextNode。 與其說是天真的,還不如說是一個糟糕的實現。 真可惜...
如果在XML中使用"<"
作為文本 ,則需要對其進行轉義,否則將其視為標記。 因此xml.dom可以將其轉義是正確的,因為您已經請求了文本節點。
假設您確實要插入XML,我建議使用createElement("hello")
。 如果您有不知道其結構的XML片段,則應首先對其進行解析,然后將解析結果的節點移至另一棵樹中。
如果要入侵,可以繼承xml.dom.minidom.Text,並覆蓋writexml方法。 有關詳細信息,請參見簡約源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.