2016-10-07 3 views
1

У меня есть XML-документ, как следующее:Удалить весь узел, используя LXML

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<parent> 
    <groupId>company</groupId> 
    <artifactId>art-id</artifactId> 
    <version>RELEASE</version> 
</parent> 

<properties> 
    <tomcat.username>admin</tomcat.username> 
    <tomcat.password>admin</tomcat.password> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>asdf</groupId> 
     <artifactId>asdf</artifactId> 
     <version>[3.8,)</version> 
    </dependency> 
    <dependency> 
     <groupId>asdf</groupId> 
     <artifactId>asdf</artifactId> 
     <version>[4.1,)</version> 
    </dependency> 
</dependencies> 

, как я могу удалить весь узел «зависимость»?

Я рассмотрел другие вопросы и ответы на stackoverflow, а другой - это аспект пространства имен этого xml, а другие вопросы попросят удалить подэлемент типа «зависимость», в то время как я хочу удалить все зависимые узлы «. Есть ли простой способ использования lxml для удаления всего узла?

Ниже дается объект А «NoneType» не имеет атрибута «удалить» ошибки:

from lxml import etree as ET 

tree = ET.parse('pom.xml') 
namespace = '{http://maven.apache.org/POM/4.0.0}' 
root = ET.Element(namespace+'project') 
root.find(namespace+'dependencies').remove() 

ответ

1

Вы можете создать отображение Dict для пространства имен (ов), найти узел затем вызвать root.remove проходя узел, вы не вызываете .remove на узле:

x = """<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<parent> 
    <groupId>company</groupId> 
    <artifactId>art-id</artifactId> 
    <version>RELEASE</version> 
</parent>  
<properties> 
    <tomcat.username>admin</tomcat.username> 
    <tomcat.password>admin</tomcat.password> 
</properties>  
<dependencies> 
    <dependency> 
     <groupId>asdf</groupId> 
     <artifactId>asdf</artifactId> 
     <version>[3.8,)</version> 
    </dependency> 
    <dependency> 
     <groupId>asdf</groupId> 
     <artifactId>asdf</artifactId> 
     <version>[4.1,)</version> 
    </dependency> 
</dependencies> 
</project>""" 
import lxml.etree as et 
from StringIO import StringIO 

tree = et.parse(StringIO(x)) 
root =tree.getroot() 

nsmap = {"mav":"http://maven.apache.org/POM/4.0.0"} 

root.remove(root.find("mav:dependencies", namespaces=nsmap)) 

print(et.tostring(tree)) 

Который даст вам:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<parent> 
    <groupId>company</groupId> 
    <artifactId>art-id</artifactId> 
    <version>RELEASE</version> 
</parent>  
<properties> 
    <tomcat.username>admin</tomcat.username> 
    <tomcat.password>admin</tomcat.password> 
</properties> 
</project> 
+0

Спасибо! Это то, что я искал. Когда я печатаю текст, закрывающий тег проекта имеет отступы, это проблема? –

+1

@ d.griner, не беспокойтесь. Не имеет значения, если вы хотите записать в файл, просто используйте 'tree.write (« out.xml », encoding =« utf-8 », xml_declaration = True)' –

+0

Не относится к окончательному решению, но isn 't автономный модуль * StringIO * удален с [Python 3] (https://docs.python.org/3/whatsnew/3.0.html)? Не следует импортировать строку: 'from io import StringIO'? – Parfait

1

Во-первых, возьмите корневой узел. Так как это <project ... > (vs <project .../>), «родительский» элемент dependencies - project. Пример из документации:

import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()

После того, как у вас есть корень, проверить root.tag(), он должен быть «проект».

Затем выполните root.remove(root.find('dependencies')), где root - это узел project.

Если бы это было <project .../>, тогда это было бы недопустимым XML, так как должен существовать корневой элемент. Я могу точно видеть, откуда вы родом.

+1

бы укоренить быть что-то вроде корня = ET.Element ("проект")? –

+0

Я только что отредактировал свой ответ, см. Обновление. Если вы делали дерево с нуля, вы могли бы определить элемент таким образом, но поскольку вы читаете из файла, вам нужно использовать 'getroot()'. –

+0

Я обновил свой код, чтобы отразить ваши изменения, но я получаю сообщение об ошибке, что удаление принимает 2 аргумента. Вы знаете, где я ошибаюсь? Спасибо за помощь. –