如何获取python中XML命名空间的前缀部分?
How to get the prefix part of XML namespace in python?
我有以下 XML(简而言之):
<?xml version="1.0" encoding="iso-8859-1"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<Proposal
xmlns="http://www.opengis.net/AAA"
xmlns:apd="http://www.opengis.net/BBB"
xmlns:common="http://www.opengis.net/DDD"
xmlns:core="http://www.opengis.net/EEE"
xmlns:pdt="http://www.opengis.net/CCC"
xmlns:xlink="http://www.opengis.net/FFF"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SchemaVersion>1.3</SchemaVersion>
<ApplicationHeader>
<ApplicationTo>W1234 </ApplicationTo>
<DateSubmitted>2021-04-26</DateSubmitted>
# ...
<Agent>
<common:PersonName>
<pdt:PersonNameTitle>Mr </pdt:PersonNameTitle>
<pdt:PersonGivenName>Holmes</pdt:PersonGivenName>
<pdt:PersonFamilyName>Sherlock</pdt:PersonFamilyName>
</common:PersonName>
<common:OrgName>Bad Company LTD</common:OrgName>
</Proposal>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我正在尝试提取 XML 标签 和 命名空间 的 prefix
部分。 (基本上它在 XML 中的样子。)使用 Python 3.10.3
,我尝试了以下的许多变体。
from lxml import html, etree
...
def list_xml_tags(xml_blob):
print(' [INFO] Printing all XML tags:')
xml = etree.fromstring(bytes(xml_blob, encoding='utf-8'))
root = etree.Element("root")
print('Root TAG: {}'.format(root))
print('nsmap : {}'.format(root.nsmap))
print('\nDescendants:')
for el in xml.iter():
el.tag = el.xpath('local-name()')
#ns = el.xpath('namespace-uri()')
#ns = etree.QName(el).namespace
#ns = root.nsmap
ns = etree.QName(el).namespace
if el.attrib == None: el.attrib =''
print('{} : {} : {}'.format(ns, el.tag, el.attrib))
但是,这不起作用。我根本无法使用它来获取命名空间。
唯一出来的就是None
。 (也不确定为什么根标签显示为地址。)
[INFO] Printing all XML tags:
------------------------------------------------------------
Root TAG: <Element root at 0x16a85fc2340>
nsmap : {}
Descendants:
None : Envelope : {}
None : Body : {}
None : Proposal : {}
None : SchemaVersion : {}
...
问:如何得到下面的输出?
SOAP-ENV : Envelope
pdt : PersonGivenName
common : OrgName
...
等
和python3
from lxml import etree
doc = etree.parse('tmp.xml')
# namespace reverse lookup dict
ns = { value:(key if key is not None else 'default') for (key,value) in set(doc.xpath('//*/namespace::*'))}
for ele in doc.iter():
qn = etree.QName(ele)
print(f"{ns[qn.namespace]:>30} : {qn.localname}")
结果:
带default
前缀的属于默认不带前缀xmlns="http://www.opengis.net/AAA"
的命名空间
SOAP-ENV : Envelope
SOAP-ENV : Body
default : Proposal
default : SchemaVersion
default : ApplicationHeader
default : ApplicationTo
default : DateSubmitted
default : Agent
common : PersonName
pdt : PersonNameTitle
pdt : PersonGivenName
pdt : PersonFamilyName
common : OrgName
我有以下 XML(简而言之):
<?xml version="1.0" encoding="iso-8859-1"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<Proposal
xmlns="http://www.opengis.net/AAA"
xmlns:apd="http://www.opengis.net/BBB"
xmlns:common="http://www.opengis.net/DDD"
xmlns:core="http://www.opengis.net/EEE"
xmlns:pdt="http://www.opengis.net/CCC"
xmlns:xlink="http://www.opengis.net/FFF"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SchemaVersion>1.3</SchemaVersion>
<ApplicationHeader>
<ApplicationTo>W1234 </ApplicationTo>
<DateSubmitted>2021-04-26</DateSubmitted>
# ...
<Agent>
<common:PersonName>
<pdt:PersonNameTitle>Mr </pdt:PersonNameTitle>
<pdt:PersonGivenName>Holmes</pdt:PersonGivenName>
<pdt:PersonFamilyName>Sherlock</pdt:PersonFamilyName>
</common:PersonName>
<common:OrgName>Bad Company LTD</common:OrgName>
</Proposal>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我正在尝试提取 XML 标签 和 命名空间 的 prefix
部分。 (基本上它在 XML 中的样子。)使用 Python 3.10.3
,我尝试了以下的许多变体。
from lxml import html, etree
...
def list_xml_tags(xml_blob):
print(' [INFO] Printing all XML tags:')
xml = etree.fromstring(bytes(xml_blob, encoding='utf-8'))
root = etree.Element("root")
print('Root TAG: {}'.format(root))
print('nsmap : {}'.format(root.nsmap))
print('\nDescendants:')
for el in xml.iter():
el.tag = el.xpath('local-name()')
#ns = el.xpath('namespace-uri()')
#ns = etree.QName(el).namespace
#ns = root.nsmap
ns = etree.QName(el).namespace
if el.attrib == None: el.attrib =''
print('{} : {} : {}'.format(ns, el.tag, el.attrib))
但是,这不起作用。我根本无法使用它来获取命名空间。
唯一出来的就是None
。 (也不确定为什么根标签显示为地址。)
[INFO] Printing all XML tags:
------------------------------------------------------------
Root TAG: <Element root at 0x16a85fc2340>
nsmap : {}
Descendants:
None : Envelope : {}
None : Body : {}
None : Proposal : {}
None : SchemaVersion : {}
...
问:如何得到下面的输出?
SOAP-ENV : Envelope
pdt : PersonGivenName
common : OrgName
...
等
和python3
from lxml import etree
doc = etree.parse('tmp.xml')
# namespace reverse lookup dict
ns = { value:(key if key is not None else 'default') for (key,value) in set(doc.xpath('//*/namespace::*'))}
for ele in doc.iter():
qn = etree.QName(ele)
print(f"{ns[qn.namespace]:>30} : {qn.localname}")
结果:
带default
前缀的属于默认不带前缀xmlns="http://www.opengis.net/AAA"
SOAP-ENV : Envelope
SOAP-ENV : Body
default : Proposal
default : SchemaVersion
default : ApplicationHeader
default : ApplicationTo
default : DateSubmitted
default : Agent
common : PersonName
pdt : PersonNameTitle
pdt : PersonGivenName
pdt : PersonFamilyName
common : OrgName