2016-10-07 13 views
1

Ich habe ein XML-Dokument wie folgt aus:Löschen gesamten Knoten mit 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> 

wie kann ich den gesamten Knoten „Abhängigkeiten“ löschen?

Ich habe andere Fragen und Antworten auf Stackoverflow untersucht und was ist anders ist der Namespace Aspekt dieser XML, und die anderen Fragen fragen ein Subelement wie "Abhängigkeit" zu löschen, während ich den gesamten Knoten "Abhängigkeiten löschen möchte . " Gibt es eine einfache Möglichkeit, mit lxml den gesamten Knoten zu löschen?

Nachfolgend ergibt eine ‚NoneType‘ Objekt kein Attribut ‚Entfernen‘ Fehler:

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() 

Antwort

1

Sie eine dict-Mapping für Ihren Namensraum (s) erstellen können, finden die Knoten dann root.remove Passieren der Knoten rufen Sie rufen auf dem Knoten nicht .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)) 

Welche würden Sie:

<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

Danke! Das habe ich gesucht. Wenn ich den Text drucke, wird das schließende Projekt-Tag eingerückt, ist das ein Problem? –

+1

@ d.griner, keine Sorgen. Es macht keinen Unterschied, wenn Sie in eine Datei schreiben wollen, verwenden Sie einfach 'tree.write (" out.xml ", encoding =" utf-8 ", xml_declaration = True)' –

+0

Nicht zur endgültigen Lösung, aber isn ist das * StringIO * Standalone-Modul seit [Python 3] (https://docs.python.org/3/whatsnew/3.0.html) entfernt? Sollte die Zeile nicht gelesen werden: 'from io import StringIO'? – Parfait

1

zuerst den Wurzelknoten greifen. Da es <project ... > ist (gegen <project .../>) ist das "Elternelement" von dependenciesproject. Beispiel aus der Dokumentation:

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

Sobald Sie die Wurzel haben, überprüfen root.tag(), sollte es „Projekt“ sein.

Dann tun root.remove(root.find('dependencies')), wo root der project Knoten ist.

Wenn es <project .../> wäre, dann wäre es ungültige XML, da es ein Wurzelelement geben muss. Ich kann jedoch genau sehen, woher du kommst.

+1

wäre so etwas wie root = ET.Element Wurzel ("Projekt")? –

+0

Ich habe gerade meine Antwort bearbeitet, siehe Update. Wenn Sie den Baum von Grund auf neu erstellen würden, könnten Sie ein Element auf diese Weise definieren, aber da Sie aus der Datei einlesen, müssen Sie 'gertroot()' verwenden. –

+0

Ich habe meinen Code aktualisiert, um Ihre Änderungen widerzuspiegeln, aber ich erhalte eine Fehlermeldung, dass remove 2 Argumente benötigt. Weißt du wo ich falsch liege? Danke für deine Hilfe. –