简体   繁体   中英

Python 3 xml parsing and printing problem

I have a sample xml file as below

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!--Created with JFLAP 7.1.--><structure>&#13;
    <type>fa</type>&#13;
    <automaton>&#13;
        <!--The list of states.-->&#13;
        <state id="0" name="q1">&#13;
            <x>104.0</x>&#13;
            <y>149.0</y>&#13;
            <initial/>&#13;
        </state>&#13;
        <state id="1" name="q2">&#13;
            <x>210.0</x>&#13;
            <y>153.0</y>&#13;
            <final/>&#13;
        </state>&#13;
        <state id="2" name="q3">&#13;
            <x>292.0</x>&#13;
            <y>155.0</y>&#13;
        </state>&#13;
        <!--The list of transitions.-->&#13;
        <transition>&#13;
            <from>0</from>&#13;
            <to>0</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>1</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>0</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>2</from>&#13;
            <to>1</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>1</from>&#13;
            <to>2</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>2</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
    </automaton>&#13;
</structure>

I'm trying to print all the name attributes of the state tag except id So far here is my code:

import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
for automaton in root.findall('automaton'):
    state = automaton.find('state')
    state_name = state.get('name')
    print(state_name)

My Current output:

q1

My Expected output:

q1
q2
q3

I'm confused because isn't the for loop in my code would print all the name attributes? Where did I do wrong and how do I fix it? Thank you~

You are lacking another findall in your code. There are multiple state tags.

See this code below. (I substituted a text io buffer for a file.)

    xml = """<?xml version="1.0" encoding="UTF-8" standalone="no"?><!--Created with JFLAP 7.1.--><structure>&#13;
    <type>fa</type>&#13;
    <automaton>&#13;
        <!--The list of states.-->&#13;
        <state id="0" name="q1">&#13;
            <x>104.0</x>&#13;
            <y>149.0</y>&#13;
            <initial/>&#13;
        </state>&#13;
        <state id="1" name="q2">&#13;
            <x>210.0</x>&#13;
            <y>153.0</y>&#13;
            <final/>&#13;
        </state>&#13;
        <state id="2" name="q3">&#13;
            <x>292.0</x>&#13;
            <y>155.0</y>&#13;
        </state>&#13;
        <!--The list of transitions.-->&#13;
        <transition>&#13;
            <from>0</from>&#13;
            <to>0</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>1</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>0</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>2</from>&#13;
            <to>1</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>1</from>&#13;
            <to>2</to>&#13;
            <read>0</read>&#13;
        </transition>&#13;
        <transition>&#13;
            <from>2</from>&#13;
            <to>1</to>&#13;
            <read>1</read>&#13;
        </transition>&#13;
    </automaton>&#13;
</structure>"""


from io import StringIO
import xml.etree.ElementTree as ET

xml_file = StringIO(xml)
tree = ET.parse(xml_file)
root = tree.getroot()
for automaton in root.findall('automaton'):
    for state in automaton.findall('state'): # find all the 'state' tags
        state_name = state.get('name')
        print(state_name)

OUTPUT:

q1
q2
q3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM