h41msh1c0r
Goto Top

Powershell Datagridview und XML Datenhaltung

Hi@PS Profi's,

ich habe 1 Datagridview(DGV) das mit Einträgen gefüllt wird.
Das Hinzufügen, Löschen und Editieren funktioniert.

Die erste Spalte ist der Zeilencounter.

Jetzt klemmt es grad an der Art und Weise wie ich mit der Datenhaltung umgehe.
Ich hatte mich für XML entschieden.

Wenn ich nun ein Element lösche was mittendrin ist, DGV leeren, Element aus dem XML entfernen und XML neu einlesen und ab ins DGV.

<?xml version="1.0" encoding="utf-8"?>  
<inhalt>
  <elements>
    <Entry Number="1">  
      <Title>
      </Title>
      <Autor>
      </Autor>
      <Shortdescription>
      </Shortdescription>
    </Entry>
    <Entry Number="2">  
      <Title>
      </Title>
      <Autor>
      </Autor>
      <Shortdescription>
      </Shortdescription>
    </Entry>
    <Entry Number="3">  
      <Title>
      </Title>
      <Autor>
      </Autor>
      <Shortdescription>
      </Shortdescription>
    </Entry>
  </elements>
</inhalt>

Da ich das Attribut Number benutze um die Stelle des Eintrages zu wissen ändert sich das natürlich über den Anzahl der Einträge wenn man was löscht.
Der erste Gedanke war ok, dann durchlauf ich halt das XML und fülle das Attribut neu.

Gibt es da einen eleganteren Weg wie ich mit dem Inhalt des XML umgehen kann?

Beim Thema Databinding bin ich noch nicht soweit, hab damit begonnen mich dazu zu belesen, wie es die Zeitfenster zulassen.

Gruß vom H41mSh1C0r

Content-ID: 301795

Url: https://administrator.de/contentid/301795

Ausgedruckt am: 24.11.2024 um 05:11 Uhr

114757
Lösung 114757 14.04.2016 aktualisiert um 10:36:32 Uhr
Goto Top
Moin.
Um es simpel zu halten würde ich zu gegebenen Zeitpunkt einfach das Datagrid durchlaufen und die XML einfach komplett neu schreiben.

Wenn man es professionell machen möchte arbeitet man hier mit XML-Serialization/Deserialization. Dazu solltest du dich aber erst mal einlesen.

Ansonsten kannst du wenn die XML wirklich live aktuell gehalten werden muss, einfach mit XPath deine Nummer im XML suchen und dann entweder entfernen oder ändern, oder bei nicht Existenz hinzufügen.
Einfaches XPath Beispiel um einen Knoten zu suchen und zu löschen:
$node = $xml.SelectSingleNode("//Entry[@Number='3']")  
$node.parent.RemoveChild($node)
Wenn es aber wirklich nur darum geht die Einstellungen am Ende des Programms zu speichern würde ich zur ersteren Methode greifen und das XML neu schreiben. Wenn man eine Datatable als Source für das DGV nutzt ist das ja auch schnell erledigt.

Ich meine das Thema hatten wir hier im Forum schon, werf mal die Suche an, da findet sich 100%prozentig auch was für Powershell.

Gruß jodel
H41mSh1C0R
H41mSh1C0R 14.04.2016 um 10:43:58 Uhr
Goto Top
Hi Jodel,

das mit dem RemoveChild hat schon funktioniert, das mach ich genau so.

Dann werd ich das wie schon gedacht erstmal neuschreiben und das Attribute neu schreiben.

Alternativ wenn ich das Attribut weglasse hab ich ja jede Menge Entry's. Dann müsste ich nur das richtige Entry finden wenn ich was lösche oder editiere. Dann kann ich mir das Umbenennen sparen und schmeiss die Spalte raus in der die laufende Nr steht.

*grübel*

Gruß
114757
114757 14.04.2016 aktualisiert um 11:13:28 Uhr
Goto Top
Naja wenn du nur einen Index brauchst, den hast du schon für jede Zeile. Per XPath lassen sich die Knoten auch per Index ansprechen, eine extra Zeile dafür ist also nicht nötig. Ein eindeutiger Bezeichner ID ist aber immer vorzuziehen, je nachdem was das DGV für Daten bereithält.
Du hast die Wahl, such dir das aus was am besten zu dir passt und womit du vor allem umgehen kannst face-wink.

Ich würde dir zu einer In-Memory Datenhaltung mit einer DataTable als Source raten welche du zu gegebenem Zeitpunkt im ganzen mit einer Funktion zurück in dein XML schreibst. Entsprechend auch eine Funktion welche die Daten aus dem XML beim Start in eine Datatable einließt.
H41mSh1C0R
H41mSh1C0R 14.04.2016 um 12:46:10 Uhr
Goto Top
ok danke dir, vorgehensweise:

- XML Einlesen
- DataTable definieren/erstellen
- XML content in die DataTable schreiben
- DataTable an das DGV binden

*rabota rabota rabota rabota *

- DataTable beim Speichern in XML zurückschreiben
114757
114757 14.04.2016 um 13:14:45 Uhr
Goto Top
jepp
colinardo
colinardo 19.04.2016 aktualisiert um 18:04:56 Uhr
Goto Top
Hallo zusammen,
eine Datatable kann per Default seine Daten in eine XML-Datei schreiben und Daten auch wieder laden:

Zum Wegschreiben:
# Datatable erstellen
$dt = New-Object System.Data.DataTable
# Wichtig: Der Datatable einen Namen geben (ohne gibt es sonst Fehler beim Exportvorgang)
$dt.TableName = "MeineDaten"  
# Spalten hinzufügen
$dt.Columns.Add('Name')  
$dt.Columns.Add('Alter')  
# Mit Demo-Daten füllen
$dt.Rows.Add(@("Max Muster","45"))  
# Daten aus der Datatable in ein XML-Dokument schreiben
$dt.WriteXml("C:\data.xml")  
Zum Einlesen:
# Datatable erstellen
$dt = New-Object System.Data.DataTable
# Wichtig: Der Datatable einen Namen geben
$dt.TableName = "MeineDaten"  
# Spalten hinzufügen
$dt.Columns.Add('Name')  
$dt.Columns.Add('Alter')  
# Daten einlesen
$dt.ReadXml("C:\data.xml")  

Automatisch erstellte XML sieht so aus:
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <MeineDaten>
    <Name>Max Muster</Name>
    <Alter>45</Alter>
  </MeineDaten>
</DocumentElement>
Oder man nutzt wie @114757 schon erwähnt hat XML (De-)Serialization

Zum wegschreiben:
# Datatable erstellen
$dt = New-Object System.Data.DataTable
# Wichtig: Der Datatable einen Namen geben (ohne gibt es sonst Fehler beim Serialisierungsvorgang)
$dt.TableName = "MeineDaten"  
# Spalten hinzufügen
$dt.Columns.Add('Name')  
$dt.Columns.Add('Alter')  
# Mit Demo-Daten füllen
$dt.Rows.Add(@("Max Muster","45"))  

# XML Serializer vom Typ DataTable erstellen
$serializer = New-Object System.Xml.Serialization.XmlSerializer([System.Data.DataTable])
# Streamwriter für die Zieldatei erstellen
$writer = New-Object System.IO.StreamWriter("C:\data.xml")  
# Daten serialisieren
$serializer.Serialize($writer,$dt)
# Streamwriter schließen
$writer.Close()
Zum Einlesen des Datatable-Objekts
# XML Serializer vom Typ DataTable erstellen
$serializer = New-Object System.Xml.Serialization.XmlSerializer([System.Data.DataTable])
# Deserialisierung mit einem Streamreader
$dt = $serializer.Deserialize((New-Object System.IO.StreamReader("C:\data.xml")))  

Die resultierende XML für das Beispiel:
<?xml version="1.0" encoding="utf-8"?>
<DataTable>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="MeineDaten" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="MeineDaten">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Name" type="xs:string" minOccurs="0" />
                <xs:element name="Alter" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <DocumentElement>
      <MeineDaten diffgr:id="MeineDaten1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
        <Name>Max Muster</Name>
        <Alter>45</Alter>
      </MeineDaten>
    </DocumentElement>
  </diffgr:diffgram>
</DataTable>
Grüße Uwe

Tags: Powershell,XML,Datagridview,Serialisierung
114757
114757 19.04.2016 aktualisiert um 18:26:51 Uhr
Goto Top
TOP, ich sehe ich war mal wieder zu faul zum Tippen ;-P
H41mSh1C0R
H41mSh1C0R 19.04.2016 um 20:24:41 Uhr
Goto Top
Hallo Uwe,

danke dir für die ausführlichen Beispiele. Ich hatte es bereits genauso mit der DataTable gemacht und es funktioniert. =)

Gibt es irgendwelche Vorteile es über Serialisierung umzusetzen?

Gruß vom H41mSh1C0r
colinardo
colinardo 19.04.2016 aktualisiert um 21:20:33 Uhr
Goto Top
Zitat von @H41mSh1C0R:
Gibt es irgendwelche Vorteile es über Serialisierung umzusetzen?
Ja, du brauchst die Struktur der Datatable hier nicht vorher manuell einrichten (Spalten, Namen,etc.) die kommt dort komplett via Schema aus der XML.

Grüße Uwe
H41mSh1C0R
H41mSh1C0R 23.04.2016 aktualisiert um 09:58:53 Uhr
Goto Top
Hallo Uwe,

danke für die Info.

Gruß vom H41mSh1C0r
(der noch fix und alle von der psconf 2016 ist, schlaf nachholen und den Kopf kühlen muss) =)