Как удалить элемент XML в Python? - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь удалить некоторые элементы в xml-файле с помощью ElementTree.Mycode не выдает никакой ошибки, но не делает то, что я хочу.Я хочу ввести CHAIN_ID и RES_POSITION, и когда я смотрю новый записанный xml-файл, я хочу видеть, что этот остаток удален.

Мой xml-файл слишком велик, поэтому вот его пример:

<SEQ>
   <CHAIN>
      <CHAIN_ID>A</CHAIN_ID>
      <RESIDUE>
         <RES_POSITION>1</RES_POSITION>
         <AA_CODE>S</AA_CODE>
      </RESIDUE>
      <RESIDUE>
         <RES_POSITION>2</RES_POSITION>
         <AA_CODE>E</AA_CODE>
      </RESIDUE>
      <RESIDUE>
         <RES_POSITION>3</RES_POSITION>
         <AA_CODE>H</AA_CODE>
      </RESIDUE>

Мой код:

def deleted_residue(mychain_id, myresidue_id, file):
    mytree = ET.parse(file)
    chain = [seq for seq in mytree.findall('.//CHAIN') if seq.findtext('.//CHAIN_ID') == mychain_id]
    sequence = [res for res in mytree.findall('.//RESIDUE') if res.findtext('.//RES_POSITION') == myresidue_id]
    for seq in chain:
        for res in sequence:
            if mychain_id == "A" and myresidue_id == "2":
                seq.remove(res)
                return deleted_residue("A", "2", "pdb_one_letter.xml")

ET.tostring(SEQ, encoding='utf8').decode('utf8')
tree.write("pdb_one_letter_deleted.xml")
from xml.dom import minidom

pdbtoxml = minidom.parseString(ET.tostring(SEQ)).toprettyxml(indent="   ")
with open("pdb_one_letter_deleted.xml", "w") as pdb:
    pdb.write(pdbtoxml)

1 Ответ

0 голосов
/ 04 марта 2019

Ваш код немного сбивает с толку;особенно часть понимания списка и использование минидома.

На основании этого:

Я пытаюсь удалить некоторые элементы в XML-файле с помощью ElementTree.Mycode не выдает никакой ошибки, но не делает то, что я хочу.Я хочу ввести CHAIN_ID и RES_POSITION, и когда я смотрю новый записанный xml-файл, я хочу видеть, что этот остаток удален.

Я думаю, что вы можете упростить тестирование значений в предикатах XPath ...

Ввод XML (test.xml)

<SEQ>
   <CHAIN>
      <CHAIN_ID>A</CHAIN_ID>
      <RESIDUE>
         <RES_POSITION>1</RES_POSITION>
         <AA_CODE>S</AA_CODE>
      </RESIDUE>
      <RESIDUE>
         <RES_POSITION>2</RES_POSITION>
         <AA_CODE>E</AA_CODE>
      </RESIDUE>
      <RESIDUE>
         <RES_POSITION>3</RES_POSITION>
         <AA_CODE>H</AA_CODE>
      </RESIDUE>
   </CHAIN>
</SEQ>

Python 3.x

import xml.etree.ElementTree as ET

def deleted_residue(mychain_id, myresidue_id, file):
    tree = ET.parse(file)
    for chain in tree.findall(f".//CHAIN[CHAIN_ID='{mychain_id}']"):
        for residue in chain.findall(f"./RESIDUE[RES_POSITION='{myresidue_id}']"):
            chain.remove(residue)
    tree.write(file)

deleted_residue("A", "2", "test.xml")

Вывод XML (измененный test.xml)

<SEQ>
   <CHAIN>
      <CHAIN_ID>A</CHAIN_ID>
      <RESIDUE>
         <RES_POSITION>1</RES_POSITION>
         <AA_CODE>S</AA_CODE>
      </RESIDUE>
      <RESIDUE>
         <RES_POSITION>3</RES_POSITION>
         <AA_CODE>H</AA_CODE>
      </RESIDUE>
   </CHAIN>
</SEQ>

Если вам нужно удалить более одного RESIDUE, было бы более разумно проанализировать XML вне функциии вместо этого перейдите в дерево.

Надеюсь, это поможет.

...