2015-07-11 5 views
0

Я пытаюсь написать код для удаления определенных узлов в XML-файле.Доступ к дочерним элементам XML в Python lxml

Я хочу, чтобы код удалял определенные узлы на основе атрибутов их родителей и детей.

Я хочу удалить <ParameterGroup> узлов, чьи родители <Task> узлов с name="Parameter Estimation", и у кого есть дети <Parameter> узлов с value="some_string".

Значение "some_string" в этом случае: "CN=Root,Model=New Model,Vector=Reactions[v1],ParameterGroup=Parameters,Parameter=Kcat,Reference=Value"

Я написал for цикл который предоставляет мне доступ к конкретным узлам, которые я хочу удалить, но когда я пытаюсь объединить в один путь он не Работа.

from lxml import etree 

NSMAP = {"c": "http://www.copasi.org/static/schema"} 

parsed = etree.parse('ct.cps') 

for task in parsed.xpath("//c:Task[@name='Parameter Estimation']", namespaces=NSMAP): 
    for group in task.xpath(".//c:ParameterGroup[@name='FitItem']", namespaces=NSMAP): 
     for parameter in group.xpath(".//c:Parameter[@value='CN=Root,Model=New Model,Vector=Reactions[v1],ParameterGroup=Parameters,Parameter=Kcat,Reference=Value']", namespaces=NSMAP): 
      print parameter.attrib['name'] 

Приведенный выше код обращается к правильному подэлементу. Однако я хочу объединить эти три уровня в один путь, чтобы удалить узел <ParameterGroup>.

Что-то вроде этого:

for a in parsed.xpath("//c:Task[@name='Parameter Estimation']/ParameterGroup[@name='FitItem']/Parameter[@value='CN=Root,Model=New Model,Vector=Reactions[v1],ParameterGroup=Parameters,Parameter=Kcat,Reference=Value']", namespaces=NSMAP): 
    parsed.remove(a) 

Но всякий раз, когда я пытаюсь это, или аналогичный, я получаю нулевой выход или ошибка о том, что XPath является неправильным.

Вот ссылка на файл XML в вопросе: https://www.dropbox.com/s/i6hga7nvmcd6rxx/ct.cps?dl=0

А вот отрывок из соответствующего раздела:

<Task key="Task_19" name="Parameter Estimation" type="parameterFitting" scheduled="false" updateModel="true"> 
    <Report reference="Report_12" target="" append="1" confirmOverwrite="1"/> 
    <Problem> 
    <Parameter name="Maximize" type="bool" value="0"/> 
    <Parameter name="Randomize Start Values" type="bool" value="0"/> 
    <Parameter name="Calculate Statistics" type="bool" value="1"/> 
    <ParameterGroup name="OptimizationItemList"> 
     <ParameterGroup name="FitItem"> 
     <ParameterGroup name="Affected Cross Validation Experiments"> 
     </ParameterGroup> 
     <ParameterGroup name="Affected Experiments"> 
     </ParameterGroup> 
     <Parameter name="LowerBound" type="cn" value="1e-06"/> 
     <Parameter name="ObjectCN" type="cn" value="CN=Root,Model=New Model,Vector=Reactions[v1],ParameterGroup=Parameters,Parameter=Kcat,Reference=Value"/> 
     <Parameter name="StartValue" type="float" value="433.724"/> 
     <Parameter name="UpperBound" type="cn" value="1e+03"/> 
     </ParameterGroup> 
     <ParameterGroup name="FitItem"> 
     <ParameterGroup name="Affected Cross Validation Experiments"> 

EDIT: Я даже не могу Подэлементы доступа, расположенные ниже <Task> узла ; это не работает (это дает нулевой выход):

for a in parsed.xpath("//c:Task[@name='Parameter Estimation']/ParameterGroup[@name='FitItem']", namespaces=NSMAP): 
    print a.attrib['name'] 

ответ

1

Вы должны уже использовали одни и те же // ось вместо / в сочетании XPath для формирования точного перевода вложенной for версии ваших кодов:

//c:Task[@name='Parameter Estimation']//c:ParameterGroup[@name='FitItem']//c:Parameter[@value='bla..bla..'] 

Использование / оси не работает главным образом потому, что ParameterGroupне прямой потомок из Task. У вас есть еще один уровень до достижения ParameterGroup от Task:

//c:Task[@name='Parameter Estimation']/*/c:ParameterGroup[@name='FitItem']/...... 
+0

Конечно, спасибо! Теперь я чувствую себя немного глупо. – Charon

Смежные вопросы