python und dokumente

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Unter Datei -> Speichern unter? Da finde ich nichts.
BlackJack

@The Hit-Man: Nein bei den ganzen Programmoptionen: `Extras→Optionen…`.

Ich habe mir mal so ein Dokument angeschaut und einem Absatz eine neue, von dem normalen Textkörper erbende Textvorlage mit dem Namen "Speziell" verpasst, und ausserdem eine Variable mit dem Namen "antwort" verwendet. Folgendes Programm:

Code: Alles auswählen

from contextlib import closing
from zipfile import ZipFile
from lxml import etree


def main():
    with closing(ZipFile('test.odt')) as odt_file:
        doc = etree.fromstring(odt_file.read('content.xml'))
    
    paragraph_node = doc.xpath('//text:p[@text:style-name="Speziell"]',
                               namespaces=doc.nsmap)[0]
    print paragraph_node.text
    
    variable_nodes = doc.xpath('//text:variable-set', namespaces=doc.nsmap)
    for variable_node in variable_nodes:
        name = variable_node.get('{%s}name' % doc.nsmap['text'])
        value = variable_node.get('{%s}value' % doc.nsmap['office'])
        print '%s = %r' % (name, value)
Hat diese Ausgabe mit dem Dokument:

Code: Alles auswählen

$ python forum5.py
Und noch ein Absatz.
antwort = '23'
XML-Namensräume sind ein wenig nervig, aber das kann man ja Notfalls in eigene Funktionen kapseln.
problembär

The Hit-Man hat geschrieben:ich habe gerade Zeit gehabt, mir ein entpacktes .odt anzuschauen. Oh jeeee, das sieht ja mal echt kompliziert aus.
Sag' ich ja ;).
BlackJack hat geschrieben:Ansonsten lohnt es sich bei grösseren XML-Dateien einen spezialisierten Editor zu verwenden, der zum Beispiel auch die Baumstruktur anzeigt und damit die Navigation erleichtert.
Unter Linux nutze ich "kxmleditor". Gefällt mir ganz gut. Ist allerdings insoweit recht rabiat, als er gar nicht erst startet, wenn er meint, die xml-Datei sei nicht "wohlgeformt".

Gruß
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@BlackJack
ich habe dein Beispiel mal ausprobiert und an mein odt angepaßt. sprich, bei mir heißt das dann nicht "Speziell", sondern "Standart". Allerdings bekomme ich schon da ein "out of range", obwohl der Tag vorhanden ist. Die Variablen hatte ich dann erst mal auskommentiert, zum testen.
BlackJack

@The Hit-Man: Ich gehe mal davon aus, dass das jetzt nur ein Tippfehler war und Du eigentlich "Standard" meintest. Die bereits vorhandenen Formate haben in der GUI allerdings andere Namen als im XML. Ich nehme mal an, damit die Namen im XML unabhängig von der Sprache sind. Also damit der typische Text in der Datei immer den gleichen Formatnamen hat, in der GUI aber je nach eingestellter Systemsprache zum Beispiel als "text body" oder "Textkörper" angezeigt wird. Du müsstest also schon im XML mal nachschauen was da wirklich als Name steht.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Wie peinlich. Es war der Tippfehler.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Also, am verzweifeln bin ich immer noch. Ich leg einfach mal den Teil des Dokuments bei, was ich bearbeiten möchte.

Code: Alles auswählen

   <text:p text:style-name="Standard"><text:variable-set text:name="name" office:value-type="string">keinen_namen</text:variable-set></text:p>
   <text:p text:style-name="Standard"><text:variable-set text:name="vname" office:value-type="string">keinen_vorname</text:variable-set></text:p>
   <text:p text:style-name="Standard"/>
   <text:p text:style-name="Standard"><text:variable-set text:name="datum" office:value-type="string">kein_datum</text:variable-set></text:p>
Habe es ja weiterhin mit Deinem Beispiel probiert, heute morgen, aber ich kann meine Variablen, wie name, vname oder datum nicht auslesen :(
Der Tippfehler hatte sich ja erledigt, trotzdem hänge ich noch :(
BlackJack

@The Hit-Man: Interessant -- die Elemente haben kein Attribut mit dem Wert sondern "nur" den Text. Könnte vielleicht daran liegen, dass Du Text als Wert hast und ich eine Zahl genommen habe. Da bestimmt ja noch einmal der Formatierungscode wie die genau dargestellt wird. Was bei Text nicht der Fall und auch nicht nötig ist.

Bei einer Zahl sieht's so aus:

Code: Alles auswählen

<text:variable-set text:name="antwort" office:value-type="float" office:value="23" style:data-style-name="N0">23</text:variable-set>
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Ja, ich habe Text Variablen genommen, denn die sollen ja auch ausgetauscht werden. Sollte doch bei xml eigentlich egal sein, dachte ich ob Text oder float. Es muß also doch ne Möglichkeit geben, den Text in der Variable zu lesen und zu setzen?
BlackJack

@The Hit-Man: Ja gibt es und das ist hier doch eigentlich ziemlich offensichtlich. Um so ein bisschen XML- und `lxml`-Grundlagen kommt man nicht drumherum.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

sagte ja, habe schon gegoogelt, wie nen wilden. Habe hier auch nen Python Buch. Da wird lxml leider nur ganz kurz angeschnitten. Vom Prinzip her, ist mir ja klar, wie das funktionieren soll/muß. Nur fand ich nirgendwo ne Doku. War schon da bei nen Python Makro zu schreiben unter OOO. Habsd auch so weit hin bekommen, das ich mein Makro unter OOO sehen konnte, nur der "Ausführen" Button ist nicht eingeschaltet. Das wäre ja auch noch ne Option. Auf Basic wollte ich eigentlich verzichten.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

das hier sieht auf den ersten Blick auch ganz brauchbar aus.
http://odfpy.forge.osor.eu/
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

The Hit-Man hat geschrieben:Nur fand ich nirgendwo ne Doku.
Komisch, denn diese ist ziemlich umfangreich.
Zuletzt geändert von Leonidas am Montag 7. Juni 2010, 00:00, insgesamt 1-mal geändert.
Grund: Link direkt auf lxml zeigen lasen
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@Leonidas
Du wirst es nicht glauben, die habe ich bei google nicht bekommen.
problembär

The Hit-Man hat geschrieben:War schon da bei nen Python Makro zu schreiben unter OOO. Habsd auch so weit hin bekommen, das ich mein Makro unter OOO sehen konnte, nur der "Ausführen" Button ist nicht eingeschaltet.
:shock: Also bei meiner zugegeben etwas älteren Office-Version kann man Python-Makros nicht im OOo-Makro-Editor schreiben, da geht nur StarBasic.
Um OOo mit Python zu steuern, muß man ein ganz normales Python-Skript schreiben und sich von außen mit OOo (über PyUNO) verbinden, wie es z.B. hier beschrieben wird.
Mann, Mann, Mann, Du machst vielleicht Sachen!
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ganz am Anfang wurde gesagt, dass auch RTF eine Option ist -> http://pypi.python.org/pypi/PyRTF/0.45

Wird aber seit 5 Jahren nicht mehr entwickelt... scheint aber zu funktionieren. Na ja, sollte zumindest mit Python 2.x funktionieren. Syntax ist ähnlich ReportLab. Nur so für den Fall, dass sich XML gegen dich durchsetzt. ;-)

Gruß, noisefloor
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@problembär
Hatte ich auch schon versucht. OOO mit Socket starten ( um eine Verbindung aufzubauen ) und dann sich mit dem Python-Script verbinden. Habe da auch einige Beispiele gefunden. Allerdings bekomme ich da keine Verbindung hin :(, denn die wird immer abgelehnt. Ach ich weiß auch nicht mehr. Hatte mir das alles irgendwie einfacher vorgestellt.
Das Problem ist nur, das muß so schnell wie möglich fertig werden. Hatte damit nicht gerechnet. Ich bin ja immer noch dafür, das alles per lxml zu steuern. Muß mich eben da noch mehr rein denken, denn gehen muß das auf jeden fall.
problembär

The Hit-Man hat geschrieben:@problembär
Hatte ich auch schon versucht. OOO mit Socket starten ( um eine Verbindung aufzubauen ) und dann sich mit dem Python-Script verbinden. Habe da auch einige Beispiele gefunden. Allerdings bekomme ich da keine Verbindung hin :(, denn die wird immer abgelehnt.
Also, das sollte aber zu machen sein. Dazu ein paar Fragen:

- OOo-Version, auf welchem OS?
- Python-Version?
- OOo-Startbefehl?
- Code des Python-Skripts?
- Fehlermeldung?

Gruß
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Ich habe mir dann doch noch mal ODFPY angeschaut, doch an einer Sache hänge ich dann doch noch rum. Ich habe mir ein Userfield in mein Dokument gebastelt. Das kann ich sogar mit ODFPY auslesen und anzeigen lassen. Nun möchste ich das aber auch setzen können. In der Doku steht, das ich eine Liste übergeben soll, mit den Feldlisten, die ich ändern möchte und die Werte. Das habe ich wie folgt gemacht:

Code: Alles auswählen

from odf.opendocument import load
from odf import text
from odf.userfield import UserFields

obj = UserFields('vorlage.odt', 'bearbeitet.odt')
# print (obj.list_fields_and_values())
obj.update (['testfeld', 'neue value des testfelds setzen'])
Als erstes übergebe ich den Namen des Feldes und dann den Wert, der gesetzt werden soll, aber bekomme eine Fehlermeldung:

Code: Alles auswählen

  File "test.py", line 7, in <module>
    obj.update (['testfeld', 'neue value des testfelds setzen'])
  File "/usr/local/lib/python2.6/dist-packages/odf/userfield.py", line 161, in update
    if data.has_key(field_name):
AttributeError: 'list' object has no attribute 'has_key'
jetzt stehe ich wieder auf dem Schlauch. Hätte ja so einfach sein können. Hat jemand ne Ahnung, warum das so ist?
http://odfpy.forge.osor.eu/manual/text.html

EDIT:
wenn ich das Feld auslese, sieht es so aus ( per ODFPY ):

Code: Alles auswählen

[('testfeld', 'string', 'mein_testfeld')]
BlackJack

@The Hit-Man: Der Docstring zu `UserField.update()` sagt, dass ein Dictionary erwartet wird (in der Doku habe ich es auf die schnelle nicht gefunden):

Code: Alles auswählen

In [1358]: UserFields.update?
Type:           instancemethod
Base Class:     <type 'instancemethod'>
String Form:    <unbound method UserFields.update>
Namespace:      Interactive
File:           /usr/lib/python2.5/site-packages/odf/userfield.py
Definition:     UserFields.update(self, data)
Docstring:
    Set the value of user fields. The field types will be the same.

    data ... dict, with field name as key, field value as value

    Returns None
Antworten