0

I'm trying to iterate over all "value" tags of "variant", the code does not jump to the next "value" key since xml has another "value" keys under "FIRST VALUE KEY"

<variant>
  <name>PROGRAMS</name>
  <value>  <!-- Lets call it FIRST VALUE KEY -->
     <value>PROG1</value>
     <statistics>
        <statistic name="Stats">
           <value>5</value>
        </statistic>
     </statistics>
  </value>
  <value>  <!-- SECOND VALUE KEY -->
     <value>PROG2</value>
     ...
  </value>
</variant>
<variant>
  <name>OTHER</name>
   ...
</variant>

Here is my python code

for keys in root.iter('variant'):
    for variant in keys:
        if variant.text == 'PROGRAMS':
            for value_tag in keys.iter('value'):
                ParamValue = value_tag.find('value').text
                    if ParamValue == 'PROG2':
                        print "GOT IT!"
                    else: continue # <- this jumps to the "<value>PROG1</value>" tag
                                   # but it should jump to the "SECOND VALUE KEY"

Where's the issue?

2
  • What is the desired output? Commented Dec 9, 2014 at 13:35
  • lets say it have to print something after if ParamValue == 'PROG2': condition Commented Dec 9, 2014 at 13:36

1 Answer 1

1
import lxml.etree as ET
root = ET.parse('data').getroot()

for value in root.xpath(
    '''//variant
           [name  
             [text()="PROGRAMS"]]
         /value
           [value
             [text()="PROG2"]]'''):
    print('GOT IT')

yields

GOT IT

I think it is easier to use XPath to dig down to the element you want. The XPath means

//                         # look for all elements
variant                    # that are variants
   [name                   # that have a <name> element
     [text()="PROGRAMS"]]  # with text equal to "PROGRAMS" 
 /value                    # select the <value> (child of variant)
   [value                  # that has a child <value> element
     [text()="PROG2"]]     # with text equal to "PROG2"

To iterate over <statistics> children of the <value> element:

for statistics in root.xpath(
    '''//variant
           [name  
             [text()="PROGRAMS"]]
         /value
           [value
             [text()="PROG2"]]
          /statistics'''):

In XPath, the brackets [..] loosely translate to "such that". Notice that without the brackets the XPath above would be //variant/value/statistics. It looks sort of like a file path. And like a file path, it shows the lineage of the element. One / means "direct child of", while // means "descendant of" (e.g. child, or grandchild or grandgrandchild, etc.).

Sign up to request clarification or add additional context in comments.

1 Comment

such an easy way to reach the destination :o but one more question, how to start iterating over that "statistics" key under PROG2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.