-2

I am writting a python script which goal is to change the value of a xml tag when matching a given criteria : here I'd like to change the active tag from true to false if the id is 'Pikachu'

When I run my python script, I get SyntaxError: invalid predicate error.

Here is my python sample code

import xml.etree.ElementTree as ET

def engineXmlCleaning(bs):
     enginePath = "Engine.xml"
     tree = ET.parse(enginePath)
     root = tree.getroot()
     
     id_to_check='pikachu'

     # Search for the element with specified ID
     matching_elements = root.findall(".//tototiti.engine.BestMatchingConfig[bestMatchingDataID/id='" + id_to_check + "']")

     # Check if element exists 
     if matching_elements:
          print("The element with id " + id_to_check + " exists.")

     for element in matching_elements:
          active_element = element.find('.//active')
          if active_element is not None:
               print('... Amending the Active value ...')
               active_element.text = 'false'

     tree.write(enginePath)

Here is a sample of xml file I'd like to amend via my script

<Engine id="1">
<bestMatchingConfigs id="50">
        <tototiti.engine.BestMatchingConfig id="51">
            <ParsingTypeName>alex_ordinate</ParsingTypeName>
            <bestMatchingDataID id="52">
                <id>pikachu</id>
            </bestMatchingDataID>
            <scriptID id="53">
                <id>pika_js</id>
            </scriptID>
            <active>true</active>
        </tototiti.engine.BestMatchingConfig>
        <tototiti.engine.BestMatchingConfig id="54">
            <ParsingTypeName>don_pillar</ParsingTypeName>
            <bestMatchingDataID id="55">
                <id>don</id>
            </bestMatchingDataID>
            <scriptID id="56">
                <id>don_js</id>
            </scriptID>
            <active>true</active>
        </tototiti.engine.BestMatchingConfig>
</bestMatchingConfigs>
</Engine>

When I run my python script, I get SyntaxError: invalid predicate error.

4
  • Please show a complete error message by copying and pasting and formatting it like code. Make sure to include all unexpected output. Commented Jan 24, 2024 at 10:45
  • Have a look at XPath SyntaxError: invalid predicate Commented Jan 24, 2024 at 10:55
  • Do you not mean if id_to_check in matching_elements: ? Id_to_check is always true, because you declare it few lines above. Commented Jan 24, 2024 at 14:42
  • The reason for the exception is because ElementTree has limited xpath support. I'd recommend using lxml instead. Commented Jan 24, 2024 at 15:49

2 Answers 2

0

Like I mentioned in the comments, the xpath support in ElementTree is limited.

If you're able to switch to lxml, you can do a more complex xpath which reduces the number of find/findall/if that need to be used (see the other answer for an example).

Example using lxml...

from lxml import etree


def engineXmlCleaning(id_to_check):
    enginePath = "engine.xml"
    tree = etree.parse(enginePath)

    for active_element in tree.xpath(f".//tototiti.engine.BestMatchingConfig[bestMatchingDataID/id='{id_to_check}']/active"):
        active_element.text = "false"

    tree.write("engine.xml")


engineXmlCleaning("pikachu")
Sign up to request clarification or add additional context in comments.

Comments

0

You can use an if condition and the find():

import xml.etree.ElementTree as ET

root = ET.parse('engine.xml').getroot()

for toto in root.findall('.//tototiti.engine.BestMatchingConfig'):
    if toto.find('bestMatchingDataID/id').text == 'pikachu':
        toto.find('active').text = 'false'

ET.indent(root, space="  ")
ET.dump(root)

Output:

<Engine id="1">
  <bestMatchingConfigs id="50">
    <tototiti.engine.BestMatchingConfig id="51">
      <ParsingTypeName>alex_ordinate</ParsingTypeName>
      <bestMatchingDataID id="52">
        <id>pikachu</id>
      </bestMatchingDataID>
      <scriptID id="53">
        <id>pika_js</id>
      </scriptID>
      <active>false</active>
    </tototiti.engine.BestMatchingConfig>
    <tototiti.engine.BestMatchingConfig id="54">
      <ParsingTypeName>don_pillar</ParsingTypeName>
      <bestMatchingDataID id="55">
        <id>don</id>
      </bestMatchingDataID>
      <scriptID id="56">
        <id>don_js</id>
      </scriptID>
      <active>true</active>
    </tototiti.engine.BestMatchingConfig>
  </bestMatchingConfigs>
</Engine>

For your xpath search you can use the part in xml.etree.ElementTree:

# Search for the element with specified ID
matching_elements = root.findall('.//*[id="pikachu"]/id')

# Check if element exists
if id_to_check == matching_elements[0].text:
    print("The element with id " + id_to_check + " exists.")

Comments

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.