-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpy2_xml.py
More file actions
173 lines (146 loc) · 6.08 KB
/
py2_xml.py
File metadata and controls
173 lines (146 loc) · 6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# coding=utf-8
import codecs
import re
__author__ = 'sinlov'
import os
from xml.dom import minidom
from xml.etree import ElementTree
class Py2MiniDom:
"""
use as python2 minidom
from tools.py2_xml import Py2MiniDom
dom = minidom.parse('test.xml')
Py2MiniDom.beauty_write(dom, 'test_test.xml')
"""
def __init__(self):
pass
@staticmethod
def read_xml_file(xml_path=str):
# type: (str) -> minidom.Document
"""
read xml file as minidom.Document
:param xml_path: xml path
:return: minidom.Document or Exception
"""
try:
if os.path.exists(xml_path):
with open(xml_path, 'r') as fh:
parse = minidom.parse(fh)
if parse:
return parse
else:
print('Error read_xml_file {0}'.format('dom is None'))
else:
raise Exception('path not found {0}'.format(xml_path))
except Exception as ex:
print('Error read_xml_file {0}'.format(ex))
pass
@staticmethod
def beauty_write(document, target_file_path=str, add_indent='\t', indent='', newline='', encode='utf-8'):
# type: (minidom.Document, str, str, str, str, str) -> None
"""
beauty xml write
:param document: for write document
:param target_file_path: target xml path
:param indent: sub element indent, default is ''
:param add_indent: add sub element indent, default is \\\\t
:param newline: sub element newline, default is ''
:param encode: write encode, default is utf-8
:return: None or print Exception
"""
try:
dom_copy = document.cloneNode(True)
f = file(target_file_path, 'wb')
writer = codecs.lookup('utf-8')[3](f)
dom_copy.writexml(writer, indent=indent, addindent=add_indent, newl=newline, encoding=encode)
dom_copy.unlink()
except Exception as ex:
print('Error beauty_write -> {0}'.format(ex))
pass
@staticmethod
def Indent(dom, node, indent=0):
# Copy child list because it will change soon
children = node.childNodes[:]
# Main node doesn't need to be indented
if indent:
text = dom.createTextNode('\n' + '\t' * indent)
node.parentNode.insertBefore(text, node)
if children:
# Append newline after last child, except for text nodes
if children[-1].nodeType == node.ELEMENT_NODE:
text = dom.createTextNode('\n' + '\t' * indent)
node.a(text)
# Indent children which are elements
for n in children:
if n.nodeType == node.ELEMENT_NODE:
Py2MiniDom.Indent(dom, n, indent + 1)
pass
@staticmethod
def del_xml_empty_line(file_path):
""" Delete blanklines of infile """
try:
if os.path.exists(file_path):
result = list()
in_fp = open(file_path, 'r')
for line in in_fp.readlines():
if not re.match(r'^\s*$', line):
result.append(line)
in_fp.close()
# print('start del_xml_empty_line count {0}'.format(len(result)))
if len(result) > 0:
out_fp = open(file_path, 'w')
out_fp.write('%s' % ''.join(result))
out_fp.close()
except Exception as ex:
print('Error del_blank_line -> {0}'.format(ex))
pass
class Py2ElementTree:
"""
for XML beauty
use like
from tools.py2_xml import Py2ElementTree
tree = ElementTree.parse('test.xml')
root = tree.getroot()
Py2ElementTree.beauty_format(root)
"""
def __init__(self):
pass
@staticmethod
def beauty_format(element, indent='\t', newline='\n', level=0):
# type: (ElementTree, str, str, int) -> None
"""
beauty XML
:param element: for beauty XML element
:param indent: indent of XML, default is \\\\t
:param newline: newline of XML, default is \\\\n
:param level: element level of XML, default is 0
:return: None this method only do element beauty
"""
if element is not None: # 判断element是否有子元素
if element.text is None or element.text.isspace(): # 如果element的text没有内容
element.text = newline + indent * (level + 1)
else:
element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
# else: # 此处两行如果把注释去掉,Element的text也会另起一行
# element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
temp = list(element) # 将 element 转成list
for sub_element in temp:
if temp.index(sub_element) < (len(temp) - 1): # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
sub_element.tail = newline + indent * (level + 1)
else: # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
sub_element.tail = newline + indent * level
# 对子元素进行递归操作
Py2ElementTree.beauty_format(sub_element, indent, newline, level=level + 1)
@staticmethod
def beauty_format_print(element, indent='\t', newline='\n', level=0):
# type: (ElementTree, str, str, int) -> None
"""
print beauty XML
:param element: for beauty XML element
:param indent: indent of XML, default is \\\\t
:param newline: newline of XML, default is \\\\n
:param level: element level of XML, default is 0
:return: None this method only do element beauty
"""
Py2ElementTree.beauty_format(element, indent, newline, level)
ElementTree.dump(element)