2012-04-05 4 views
2

Bitte ertragen Sie mich, da ich Python (und die größere Programmiergemeinschaft) SEHR neu bin, aber ich wurde von einem Mitarbeiter mit mehr Erfahrung als ich geführt. Ich versuche, ein Python-Skript zu schreiben, das eine XML-Datei einliest und bestimmte Teile der Daten auseinander nimmt, einige der Variablenwerte bearbeitet und dann das XML wieder zusammenfügt. Das Problem, auf das wir stoßen, ist in der Art, wie die Daten formatiert werden, während sie an die neue Ausgabe mit toprettyxml() übergeben werdenPython-Problem mit xml.dom.minidom Dokument. Extra leere Zeilen zwischen Kindelementen mit toprettyxml()

Grundsätzlich hat die obere Hälfte der Datei eine Reihe von Elementen, die wir Sie brauchen gar nicht zu modifizieren, also versuchen wir, diese Elemente in ihrer Gesamtheit zu erfassen und sie dann wieder an die Wurzel anzuhängen, wenn wir sie wieder zusammensetzen. Einige der unteren Elemente auf derselben Seite auf derselben Ebene werden in kleinere Elemente im Speicher getrennt und auf den niedrigsten untergeordneten Ebenen wieder zusammengesetzt. Diejenigen, die manuell zusammengebaut und angehängt werden, funktionieren gut.

Also hier ist, was etwa die entsprechenden Bits von Code sein sollte:

def __handleElemsWithAtrributes(elem): 
    #returns empty element with all attributes of source element 
    tmpDoc = Document() 
    result = tmpDoc.createElement(elem.item(0).tagName) 
    attr_map = elem.item(0).attributes 
    for i in range(attr_map.length): 
     result.setAttribute(attr_map.item(i).name,attr_map.item(i).value) 
    return result 

def __getWholeElement(elems): 
    #returns element with all attributes of source element and all contents 
    if len(elems) == 0: 
     return 0 
    temp = Document() 
    for e in elems: 
     result = temp.createElement(e.tagName) 
     attr_map = e.attributes 
     for i in range(attr_map.length): 
      result.setAttribute(attr_map.item(i).name,attr_map.item(i).value) 
     result = e 
    return result 


def __init__(): 
     ##A bunch of other stuff I'm leaving out... 
       f = xml.dom.minidom.parse(pathToFile) 
       doc = Document() 

       modules = f.getElementsByTagName("Module") 
       descriptions = f.getElementsByTagName("Description") 
       steptree = f.getElementsByTagName("StepTree") 
       reference = f.getElementsByTagName("LessonReference") 

       mod_val = __handleElemsWithAtrributes(modules) 
       des_val = __getWholeElement(descriptions) 
       step_val = __getWholeElement(steptree) 
       ref_val = __getWholeElement(reference) 

       if des_val != 0 and mod_val != 0 and step_val != 0 and ref_val != 0: 
        mod_val.appendChild(des_val) 
        mod_val.appendChild(step_val) 
        mod_val.appendChild(ref_val) 
        doc.appendChild(mod_val) 
       o.write(doc.toprettyxml()) 

Nein, die tabbing nicht genau hier aufbewahrt, weil ich aus verschiedenen Bereichen kopiert, aber ich bin sicher, dass Sie das Wesentliche zu bekommen.

Grundsätzlich ist die Eingabe Ich benutze sieht etwa so aus:

<Module aatribute="" attribte2="" attribute3="" > 
<Description> 
    <Title>SomeTitle</Title> 
    <Objective>An objective</Objective> 
    <Action> 
     <Familiarize>familiarize text</Familiarize> 
    </Action> 
    <Condition> 
     <Familiarize>Condition text</Familiarize> 
    </Condition> 
    <Standard> 
     <Familiarize>Standard text</Familiarize> 
    </Standard> 
    <PerformanceMeasures> 
     <Measure>COL text</Measure> 
    </PerformanceMeasures> 
    <TMReferences> 
     <Reference>Reference text</Reference> 
    </TMReferences> 
</Description> 

Und dann, wenn es zusammengesetzt ist, es kommt etwas wie folgt aussehen:

<Module aatribute="" attribte2="" attribute3="" > 
<Description> 


    <Title>SomeTitle</Title> 


    <Objective>An objective</Objective> 


    <Action> 


     <Familiarize>familiarize text</Familiarize> 


    </Action> 


    <Condition> 


     <Familiarize>Condition text</Familiarize> 


    </Condition> 


    <Standard> 


     <Familiarize>Standard text</Familiarize> 


    </Standard> 


    <PerformanceMeasures> 


     <Measure>COL text</Measure> 


    </PerformanceMeasures> 


    <TMReferences> 


     <Reference>Reference text</Reference> 


    </TMReferences> 


</Description> 

Wie bekomme ich es Hör auf alle extra Leerzeilen zu machen? Irgendwelche Ideen?

Antwort

2

Ich habe das gleiche Problem. Die Sache ist, jedes Mal wenn Python eine Zeile springt, fügt es einen textNode in Ihrem Baum dafür hinzu. Daher ist topprettyxml() eine sehr bösartige Funktion, weil es Knoten zu Ihrem Baum hinzufügt, ohne dass Sie sich dessen bewusst sind.

Eine der Lösungen wäre, eine Möglichkeit zu finden, alle nutzlosen textNodes zu löschen, wenn Sie Ihre Datei am Anfang analysieren (ich suche es gerade noch, habe noch keine "hübsche" Lösung gefunden).

löschen Knoten für Knoten:

def cleanUpNodes(nodes): 
    for node in nodes.childNodes: 
     if node.nodeType == Node.TEXT_NODE: 
      node.data = '' 
    nodes.normalize() 

von http://mail.python.org/pipermail/xml-sig/2004-March/010191.html

-1

Danke das funktioniert rekursiv !!

def cleanUpNodes(self,nodes): 
     for node in nodes.childNodes: 
      if node.nodeType == node.TEXT_NODE and (node.data.startswith('\t') or node.data.startswith('\n') or node.data.startswith('\r')): 
       node.data = '' 
      if node.nodeType == node.ELEMENT_NODE: 
       self.cleanUpNodes(node) 
     nodes.normalize() 
Verwandte Themen