針對節點名稱以數字開頭、非標準格式的 XML,以正則表達式實作輕量級 XPath 風格解析器。
import re
class xmlparse:
def __init__(self, xmlstr):
self.xmlstr = xmlstr
self.xmldom = self.__convet2utf8()
self.xmlnodelist = []
self.xpath = ''
def __get_head(self):
m = re.match(r'<\?xml.*?\?>', self.xmlstr)
return m.group() if m else ''
def __convet2utf8(self):
head = self.__get_head()
body = self.xmlstr.replace(head, '')
if 'gbk' in head:
return body.decode('gbk').encode('utf-8')
elif 'gb2312' in head:
return body.decode('gb2312').encode('utf-8')
return body
def parse(self, xpath):
self.xpath = xpath
xpatlist = []
for node in xpath.split('/'):
if not node: continue
idx = 0
if '[' in node:
node, idx = node.split('[')
idx = int(idx.rstrip(']'))
xpatlist.append((f'<{node}>(.*?){node}>', idx))
xmlstr = self.xmldom
for pat, idx in xpatlist:
nodes = re.findall(pat, xmlstr)
xmlstr = nodes[idx]
if xmlstr.startswith('
xmlstr = 'aaaaa ... '
xp = xmlparse(xmlstr)
print(xp.parse('/product_id')) # aaaaa
print(xp.parse('/product_id[1]')) # bbbbb
print(xp.parse('/a/product_id')) # aaaaa
lxml 或 xml.etree