[Python] How to replace xml node value in Python, without changing the whole file

Discussão em 'Python' iniciado por Stack, Dezembro 19, 2024.

  1. Stack

    Stack Membro Participativo

    Doing my first steps in python I try to parse and update a xml file. The xml is as follows:

    <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet href="util/style/aaaa-2-0.xsl" type="text/xsl"?>
    <test dtd-version="3.2" xmlns:test="http://www.ich.org/test" xmlns:xlink="http://www.w3c.org/1999/xlink">
    <mr>
    <leaf checksum="88ed245997a341a4c7d1e40d614eb14f" >
    <title>book name</title>
    </leaf>
    </mr>
    </test>


    I would like to update the value of the checksum.I have written a class with one method:

    @staticmethod
    def replace_checksum_in_index_xml(xml_file_path, checksum):
    logging.debug(f"ReplaceChecksumInIndexXml xml_file_path: {xml_file_path}")
    try:
    from xml.etree import ElementTree as et
    tree = et.parse(xml_file_path)
    tree.find('.//leaf').set("checksum", checksum)
    tree.write(xml_file_path)
    except Exception as e:
    logging.error(f"Error updating checksum in {xml_file_path}: {e}")


    I call the method:

    xml_file_path = "index.xml"
    checksum = "aaabbb"
    Hashes.replace_checksum_in_index_xml(xml_file_path, checksum)


    The checksum is indeed updated. But also the whole xml structure is changed:

    <test dtd-version="3.2">
    <mr>
    <leaf checksum="aaabbb">
    <title>book name</title>
    </leaf>
    </mr>
    </test>


    How can I update only given node, without changing anything else in given xml file?

    UPDATE

    Solution provided by LRD_Clan is better than my original one. But it is still changing a bit the structure of xml. Also when I take more complex example I see again part of xml is removed. More complex example with additional DOCTYPE:

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE eu:eu-backbone SYSTEM "../../util/dtd/eu-regional.dtd"[]>
    <?xml-stylesheet href="util/style/aaaa-2-0.xsl" type="text/xsl"?>

    <test dtd-version="3.2" xmlns:test="http://www.ich.org/test" xmlns:xlink="http://www.w3c.org/1999/xlink">
    <mr>
    <leaf checksum="88ed245997a341a4c7d1e40d614eb14f" >
    <title>book name</title>
    </leaf>

    </mr>
    </test>


    after running updated script the result is:

    <?xml version='1.0' encoding='UTF-8'?>
    <?xml-stylesheet href="util/style/aaaa-2-0.xsl" type="text/xsl"?><test xmlns:test="http://www.ich.org/test" xmlns:xlink="http://www.w3c.org/1999/xlink" dtd-version="3.2">
    <mr>
    <leaf checksum="aaabbb">
    <title>book name</title>
    </leaf>
    </mr>
    </test>


    I would really like to see only this one xml element being changed and the other part of document to be left intact.

    I had similiar solution written in powershell which looks like

    [xml]$xmlContent = Get-Content -Path $xmlFilePath
    $element = $xmlContent.SelectSingleNode("//leaf")
    $element.SetAttribute("checksum, "new text")
    $xmlContent.Save((Resolve-Path "$xmlFilePath").Path)


    I was hoping I will find something at least same elegant in python.

    Continue reading...

Compartilhe esta Página