Hướng dẫn how to loop through xml elements in python - cách lặp qua các phần tử xml trong python

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 user:

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 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

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
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 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 get
        
0 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 get
        
1 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 get
        
3 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

Làm cách nào để lặp lại thẻ XML trong Python?

Để lặp lại trên tất cả các nút, sử dụng phương thức ITER trên ElementTree, không phải phần tử gốc. Rễ là một yếu tố, giống như các yếu tố khác trong cây và chỉ thực sự có bối cảnh của các thuộc tính và trẻ em của chính nó. ElementTree có bối cảnh cho tất cả các yếu tố.use the iter method on the ElementTree , not the root Element. The root is an Element, just like the other elements in the tree and only really has context of its own attributes and children. The ElementTree has the context for all Elements.

Làm cách nào để lặp một nút XML?

Cách lặp qua XML trong JavaScript..
Tìm phần tử theo tên thẻ ..
Vòng lặp qua từng phần tử XML ..
Đối với mỗi phần tử, hãy lấy NodeValue bên trong sẽ trả lại văn bản ..
Tạo một nút DOM mới bằng cách sử dụng CreatetExtNode ..
Nối nút này vào DOM ..

Làm thế nào để bạn xử lý XML trong Python?

Để đọc một tệp XML bằng ElementTree, trước tiên, chúng tôi nhập lớp ElementTree được tìm thấy bên trong thư viện XML, dưới tên ET (thông tin chung).Sau đó chuyển tên tệp của tệp XML cho ElementTree.Phương thức Parse (), để cho phép phân tích tệp XML của chúng tôi.Sau đó, nhận được gốc (thẻ cha) của tệp XML của chúng tôi bằng GetRoot ().

XML Etree ElementTree là gì?

XML.Etree.Mô -đun ElementTree thực hiện một API đơn giản và hiệu quả để phân tích và tạo dữ liệu XML.Thay đổi trong phiên bản 3.3: Mô -đun này sẽ sử dụng triển khai nhanh bất cứ khi nào có sẵn.implements a simple and efficient API for parsing and creating XML data. Changed in version 3.3: This module will use a fast implementation whenever available.