XML Datei bearbeiten

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.
Antworten
Gast

Hallo.
Mein erster Beitrag hier.

Ich habe ein kleines Problem mit XML.
Bin noch nicht so bewndelt in der XML Materie also bitte übt Nachsicht. :wink:

Ich möchte einfach nur eine XML Datei per Script bearbeiten.
XML öffnen:

Code: Alles auswählen

self.doc = xml.dom.minidom.parse(Datei)
Danach lese ich den ganzen kram in ein Dic und lasse alles bearbeiten.
Jetzt will ich das ganze natürlich auch speichern allerdings will das nich so wie ich.
Das speichern an sich ist nicht das Problem sodern viel mehr das die änderungen nich übernommen werden.
Nach dem speichern sieht die Datei aus wie vorher.
Also hab ich zum Test mal einen Eintrag direkt verändern wollen:

Code: Alles auswählen

aefile='D:\\DialogSubMenu.xml'
self.doc.childNodes[0].childNodes[3].nodeValue="test"

f = open(aefile, 'w')
self.doc.writexml(f)
f.close()
Und: Nix. Originalfile und bearbeitetes sind exakt identisch.
Was mach ich falsch?

Edit (Leonidas): Code in Python-Tags gesetzt.
Rockstar
User
Beiträge: 15
Registriert: Samstag 12. November 2005, 17:31
Kontaktdaten:

Mist. :lol:
Hatte nach dem anmelden vergessen mich eizuloggen. :roll:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Könntest du mal so ein kleines XML posten?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Rockstar
User
Beiträge: 15
Registriert: Samstag 12. November 2005, 17:31
Kontaktdaten:

Klar.
Wollte die Datei anhängen aber die möglichkeit gibts nicht oder?

Code: Alles auswählen

<window>
  <id>105</id>
  <visible effect="fade" time="200" start="hidden">Window.IsActive(105)</visible>
  <!--  Change the defaultcontrol ID to have another button focussed when  !-->
  <!--  you bring the panel up.                                            !-->
  <!--  (look for this tag: <id>1123</id> on the button u want to focus)   !-->
  <defaultcontrol>1109</defaultcontrol>
  <type>buttonMenu</type>
  <coordinates>
    <system>1</system>
    <posX>500</posX>
    <posY>70</posY>
  </coordinates>

  <controls>
    <control>
      <type>image</type>
      <id>0</id>
      <posX>10</posX>
      <posY>15</posY>
      <width>160</width>
      <height>440</height>
      <texture>subpanel.png</texture>
    </control>

    <!--  To add another button to the submenu, just put in your hyperlink,  !-->
    <!--  give it the desired label and set visible to YES!                  !-->
    <!--  To link direct to a script,xbe/audio/video file use (eg):          !-->
    <!--  <execute>F:\Emulators\ScummVMx\default.xbe</execute>               !-->
    <!--  To link to a XBMC screen use                                       !-->
    <!--  <execute>XBMC.ActivateWindow('ID here')</execute>                  !-->
    <control>
      <description>SubMenu button</description>	<visible>no</visible>
      <type>button</type>				<execute>q:\scripts\-.py</execute>
      <id>1123</id>					<label>-</label>
      <posX>30</posX>
      <posY>110</posY>
      <width>110</width>
      <height>20</height>
      <font>font101</font>
      <onleft>1123</onleft>
      <onright>1123</onright>
      <onup>1109</onup>
      <ondown>1122</ondown>
      <align>center</align>
      <textOffsetY>-1</textOffsetY>
      <textureNoFocus>-</textureNoFocus>
    </control>

    <control>
      <description>SubMenu button</description>	<visible>no</visible>
      <type>button</type>				<execute>q:\scripts\-.py</execute>
      <id>1122</id>					<label>-</label>
      <posX>30</posX>
      <posY>130</posY>
      <width>110</width>
      <height>20</height>
      <font>font101</font>
      <onleft>1122</onleft>
      <onright>1122</onright>
      <onup>1123</onup>
      <ondown>1121</ondown>
      <align>center</align>
      <textOffsetY>-1</textOffsetY>
      <textureNoFocus>-</textureNoFocus>
    </control>

    <control>
      <description>SubMenu button</description>	<visible>no</visible>
      <type>button</type>				<execute>q:\scripts\-.py</execute>
      <id>1121</id>					<label>-</label>
      <posX>30</posX>
      <posY>150</posY>
      <width>110</width>
      <height>20</height>
      <font>font101</font>
      <onleft>1121</onleft>
      <onright>1121</onright>
      <onup>1122</onup>
      <ondown>1120</ondown>
      <align>center</align>
      <textOffsetY>-1</textOffsetY>
      <textureNoFocus>-</textureNoFocus>
    </control>

  </controls>

</window>
Hab n bisschen was weggelassen damits nicht ganz so viel wird.
Da sind nur noch mehr von den Control Blöcken drin.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die Möglichkeit Dateien anzuhängen gibt es nicht, aber dafür reicht auch Copy&Paste.

Ich habe dir mal ein Script geschrieben, dass den Wert von Defaultcontrol auf test setzt:

Code: Alles auswählen

import xml.dom.minidom

aefile = 'domexample.xml'
outfile = 'domoutput.xml'
doc = xml.dom.minidom.parse(aefile)
defaultcontrol = doc.getElementsByTagName('defaultcontrol')[0].childNodes[0]
print defaultcontrol.nodeValue
defaultcontrol.nodeValue = 'test'

f = file(outfile, 'w')
doc.writexml(f)
f.close()
Bei fragen, einfach fragen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Rockstar
User
Beiträge: 15
Registriert: Samstag 12. November 2005, 17:31
Kontaktdaten:

Ach so.
Wenn ich das vorher in ne Variable auslager kann ich der dann nen Wert zuweisen?!?
Sind die irgendwie miteinander verküpft?
Sowas hätt ich ja jetzt gar nicht erwartet.

Allerdings gibts damit trotzdem Probleme. :?
Wenn ich deinen Code jetzt abänder das im zweiten Control-Block das zweite Tag geändert wird steht das wort test am ende nicht im Tag sondern ausserhalb.

Also so der Code:

Code: Alles auswählen

import xml.dom.minidom

aefile = 'D:\\domexample.xml'
outfile = 'D:\\domoutput.xml'
doc = xml.dom.minidom.parse(aefile)
defaultcontrol = doc.childNodes[0].getElementsByTagName("controls")[0].getElementsByTagName("control")[1].childNodes[1]
print defaultcontrol.nodeValue
defaultcontrol.nodeValue = 'test'

f = file(outfile, 'w')
doc.writexml(f)
f.close()
Und die Datei am Ende:

Code: Alles auswählen

...
<control>
      <description>SubMenu button</description>test<visible>no</visible>
      <type>button</type>				<execute>q:\scripts\-.py</execute>
      <id>1123</id>					<label>-</label>
      <posX>30</posX>
      <posY>110</posY>
      <width>110</width>
      <height>20</height>
      <font>font101</font>
      <onleft>1123</onleft>
      <onright>1123</onright>
      <onup>1109</onup>
      <ondown>1122</ondown>
      <align>center</align>
      <textOffsetY>-1</textOffsetY>
      <textureNoFocus>-</textureNoFocus>
    </control>
...
Nur der betroffene Control Block.
Ich verstehs nich.

Aber schon mal danke das du dir die Mühe machst!

Edit (Leonidas): Code in Python-Tags gesetzt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Erst mal: Könntest du den Python-Code statt in Code-Tags in Python-Tags setzen? Sonst muss ich immer deine Beiträge hinterhereditieren :?
Rockstar hat geschrieben:Wenn ich das vorher in ne Variable auslager kann ich der dann nen Wert zuweisen?!?
Kannst du, musst du aber nicht. Ich habe es nur deswegen gemacht, damit das Programm lesbarer ist.
Rockstar hat geschrieben:Sind die irgendwie miteinander verküpft?
Variablen sind in Python (und Ruby und anderen Programmiersprachen) nur Namen für Objekte, so dass man auch auf das gleiche Objekt mit mehreren Namen zugreifen kann. Ein Beispiel:

Code: Alles auswählen

In [6]: a = set([1, 2, 3])
In [7]: b = a
In [8]: b.add(4)
In [9]: a
Out[9]: set([1, 2, 3, 4])
In [10]: id(a)
Out[10]: 1348442432
In [11]: id(b)
Out[11]: 1348442432
In [12]: a is b
Out[12]: True
Du siehst, dass man über b das Objekt verändert hat, welches auch als a bekannt ist, wenn man es sich genauer ansieht, stellt man fest, dass das Objekt welches an a und das an b sogar die gleiche ID besitzen, also das gleiche Objekt sind. Das mag vielleicht etwas komisch erscheinen, jedoch ist es oftmals praktisch, es wäre komisch wenn es sich anders verhalten würde.
Rockstar hat geschrieben:Allerdings gibts damit trotzdem Probleme. :?
Wenn ich deinen Code jetzt abänder das im zweiten Control-Block das zweite Tag geändert wird steht das wort test am ende nicht im Tag sondern ausserhalb.
Ja, das liegt daran, dass du die Struktur vom DOM nicht ganz verstehst (btw: ich auch nicht, aber dafür reicht es). Am besten demonstriere ich es dir an einem Bespiel:

Code: Alles auswählen

import xml.dom.minidom

aefile = 'domexample.xml'
outfile = 'domoutput.xml'
doc = xml.dom.minidom.parse(aefile)

controls = doc.getElementsByTagName('control')
print controls
print controls[1].childNodes
visiblenode = controls[1].childNodes[3]
print visiblenode
visible_textnode = visiblenode.childNodes[0]
print visible_textnode
visible_textnode.nodeValue = 'test'

f = file(outfile, 'w')
doc.writexml(f)
f.close()
Erstmal suche ich im DOM-Tree nach allen Control-Elementen. Dann bekomme ich die folgenden:

Code: Alles auswählen

[<DOM Element: control at 0xa962d8>, <DOM Element: control at 0xab50d0>, <DOM Element: control at 0xab5cb0>, <DOM Element: control at 0xabb8c8>]
Gut, du wolltest das zweite Element, also controls[1]. Dies hat folgende Nodes:

Code: Alles auswählen

[<DOM Text node "\n      ">, <DOM Element: description at 0xab2148>, <DOM Text node "    ">, <DOM Element: visible at 0xab21e8>, <DOM Text node "\n      ">, <DOM Element: type at 0xab2288>, <DOM Text node "          ...">, <DOM Element: execute at 0xab2328>, <DOM Text node "\n      ">, <DOM Element: id at 0xab23c8>, <DOM Text node "          ...">, <DOM Element: label at 0xab2468>, <DOM Text node "\n      ">, <DOM Element: posX at 0xab2508>, <DOM Text node "\n      ">, <DOM Element: posY at 0xab25a8>, <DOM Text node "\n      ">, <DOM Element: width at 0xab2648>, <DOM Text node "\n      ">, <DOM Element: height at 0xab26e8>, <DOM Text node "\n      ">, <DOM Element: font at 0xab2788>, <DOM Text node "\n      ">,
 <DOM Element: onleft at 0xab2828>, <DOM Text node "\n      ">, <DOM Element: onright at 0xab28c8>, <DOM Text node "\n      ">, <DOM Element: onup at 0xab2968>, <DOM Text node "\n      ">, <DOM Element: ondown at 0xab2a08>, <DOM Text node "\n      ">, <DOM Element: align at 0xab2aa8>, <DOM Text node "\n      ">, <DOM Element: textOffsetY at 0xab2b48>, <DOM Text node "\n      ">, <DOM Element: textureNoFocus at 0xab2be8>, <DOM Text node "\n    ">]
Wie du siehst ist hier das Element visible an 4. Stelle, also controls[1].childNodes[3].

Code: Alles auswählen

<DOM Element: visible at 0xab21e8>
Jedoch hat auch das Visible-tag noch einen childNode: den Text-Node visiblenode.childNodes[0]

Code: Alles auswählen

<DOM Text node "no">
Dieser Node hat einen Wert, nodeValue, der ist im Moment "no". Nun kannst du ihn auf "test" setzen und die XML-Datei generieren.

DOM ist eigentlich ganz einfach, wenn man weiß, welche Nodes welche childNodes haben, da brauchst du einfach nur ein wenig Übung.
Zuletzt geändert von Leonidas am Sonntag 13. November 2005, 13:18, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

Leonidas hat geschrieben:Erst mal: Könntest du den Python-Code statt in Code-Tags in Python-Tags setzen? Sonst muss ich immer deine Beiträge hinterhereditieren :?
Das hab ich versucht aber ich finde nur den Code Button.
Einfach python als tag verwenden?
Leonidas hat geschrieben:Variablen sind in Python (und Ruby und anderen Programmiersprachen) nur Namen für Objekte, so dass man auch auf das gleiche Objekt mit mehreren Namen zugrefien kann.
Jap. Bins halt nur nicht so gewohnt.
Bin gewohnt das wenn ich ne neue Variable deklariere die eine völlig eigenständige ist und keinen Bezug zum original Objekt hat.

Aber vielen Dank schon mal.
Hast mir auf jeden Fall riesig geholfen.
Und mit dem Dom XML Kram komm ich so langsam auch klar.
Danke. :D
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Anonymous hat geschrieben:Das hab ich versucht aber ich finde nur den Code Button.
Einfach python als tag verwenden?
Ja, python und /python in eckigen Klammern.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten