Mặc dù iter[]
là rất tốt, tôi cần một cách để đi bộ phân cấp XML trong khi theo dõi mức độ làm tổ và iter[]
hoàn toàn không giúp ích gì cho điều đó. Tôi muốn một cái gì đó như iterparse[]
phát ra các sự kiện bắt đầu và kết thúc ở mỗi cấp độ của hệ thống phân cấp, nhưng tôi đã có ElementTree nên không muốn bước/chi phí không cần thiết của việc chuyển đổi thành chuỗi và phân loại lại rằng sử dụng iterparse[]
sẽ yêu cầu.
Ngạc nhiên tôi không thể tìm thấy điều này, tôi đã phải tự viết nó:
def iterwalk[root, events=None, tags=None]:
"""Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if empty/None events are generated for all tags
"""
# each stack entry consists of a list of the xml element and a second entry initially None
# if the second entry is None a start is emitted and all children of current element are put into the second entry
# if the second entry is a non-empty list the first item in it is popped and then a new stack entry is created
# once the second entry is an empty list, and end is generated and then stack is popped
stack = [[root,None]]
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def iterator[]:
while stack:
elnow,children = stack[-1]
if children is None:
# this is the start of elnow so emit a start and put its children into the stack entry
if [ not tags or elnow.tag in tags ] and "start" in events:
yield ["start",elnow]
# put the children into the top stack entry
stack[-1][1] = list[elnow]
elif len[children]>0:
# do a child and remove it
thischild = children.pop[0]
# and now create a new stack entry for this child
stack.append[[thischild,None]]
else:
# finished these children - emit the end
if [ not tags or elnow.tag in tags ] and "end" in events:
yield ["end",elnow]
stack.pop[]
return iterator
# myxml is my parsed XML which has nested Binding tags, I want to count the depth of nesting
# Now explore the structure
it = iterwalk[ myxml, tags='Binding']]
level = 0
for event,el in it[]:
if event == "start":
level += 1
print[ f"{level} {el.tag=}" ]
if event == "end":
level -= 1
Ngăn xếp được sử dụng để bạn có thể phát ra các sự kiện bắt đầu khi bạn đi xuống phân cấp và sau đó quay lại chính xác. Mục cuối cùng trong ngăn xếp ban đầu là [el, không] vì vậy sự kiện bắt đầu cho EL được phát ra và mục thứ hai là cập nhật cho [el, trẻ em] với mỗi đứa trẻ bị loại khỏi trẻ em khi nó được nhập vào đã được thực hiện, mục nhập là [el, []] tại thời điểm đó sự kiện kết thúc cho EL được phát ra và mục nhập cùng được xóa khỏi ngăn xếp.
Tôi đã làm theo cách này với ngăn xếp bởi vì tôi không thích gỡ lỗi mã đệ quy và dù sao tôi cũng không chắc chắn làm thế nào để viết một chức năng lặp lại đệ quy.
Đây là phiên bản đệ quy dễ hiểu hơn nhưng sẽ khó gỡ lỗi nếu nó không đơn giản và có gì đó không ổn - và tôi đã biết về yield from
:-]
def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
Thông thường XML có nhiều nút và chúng ta cần viết một vòng lặp để xử lý tất cả các nút. Trong chương trình sau, chúng tôi lặp qua tất cả các nút Bạn nghĩ mã này sẽ in gì? Chạy nó để xem những gì nó thực sự in. Phương pháp user
:findall
lấy một danh sách python của các cây con đại diện cho các cấu trúc user
trong cây XML. Sau đó, chúng ta có thể viết một vòng lặp
1 nhìn vào từng nút người dùng và in các phần tử văn bản def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
2 và def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
3 cũng như thuộc tính def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
4 từ nút def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
user
.
Đặt các khối sau để sử dụng một vòng lặp để xử lý các nút trong chương trình XML, giống như các khối được thấy ở trên.
Use findall to retrieve subtrees representing user structures in the XML tree. --- Use a for each loop to loop through the user nodes --- Print the name and id from the user node --- Print the x attribute from the user node using get
Điều quan trọng là bao gồm tất cả các yếu tố cấp cha mẹ trong câu lệnh findall
ngoại trừ phần tử cấp cao nhất [ví dụ:
def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
7]. Nếu không, Python sẽ không tìm thấy bất kỳ nút mong muốn nào.Bạn nghĩ mã này sẽ in gì? Chạy nó để xem những gì nó thực sự in.
def iterwalk1[root, events=None, tags=None]:
"""Recuirsive version - Incrementally walks XML structure [like iterparse but for an existing ElementTree structure]
Returns an iterator providing [event, elem] pairs.
Events are start and end
events is a list of events to emit - defaults to ["start","end"]
tags is a single tag or a list of tags to emit events for - if None or empty list then events are generated for all tags
"""
tags = [] if tags is None else tags if type[tags] == list else [tags]
events = events or ["start","end"]
def recursiveiterator[el,suppressyield=False]:
if not suppressyield and [ not tags or el.tag in tags ] and "start" in events:
yield ["start",el]
for child in list[el]:
yield from recursiveiterator[child]
if not suppressyield and [ not tags or el.tag in tags ] and "end" in events:
yield ["end",el]
def iterator[]:
yield from recursiveiterator[ root, suppressyield=True ]
return iterator
8 lưu trữ tất cả các yếu tố user
được lồng trong phụ huynh Use findall to retrieve subtrees representing user structures in the XML tree. --- Use a for each loop to loop through the user nodes --- Print the name and id from the user node --- Print the x attribute from the user node using get0 của họ.
Use findall to retrieve subtrees representing user structures in the XML tree. --- Use a for each loop to loop through the user nodes --- Print the name and id from the user node --- Print the x attribute from the user node using get1 tìm kiếm các yếu tố
user
không được lồng trong phần tử cấp cao nhất Use findall to retrieve subtrees representing user structures in the XML tree. --- Use a for each loop to loop through the user nodes --- Print the name and id from the user node --- Print the x attribute from the user node using get3 nơi không có.
CSP-10-2-4: Để Python tìm thấy các nút mong muốn, điều quan trọng là phải bao gồm tất cả các phần tử cấp ______ trong câu lệnh findall
mong đợi cho phần tử cấp cao nhất.
Bạn đã thử các hoạt động trên trang này of activities on this page