marcoborn
Goto Top

Knoten in XML-Dokument verschieben

Hallo Forum,
ich habe eine XML-Datei mit ca.20.000 Datensätzen. Die haben folgende Grundstruktur:
  <INDI_L0 OrigID="@I10@" >  
    <NAME_L1 Value="Kurt Andres" />  
    <SEX_L1 Value="M" />  
    <_UID_L1 Value="db4b4267-51e8-4f66-9272-29187e29b57c" />  
    <BIRT_L1 Value="">  
      <DATE_L2 Value="18 JUN 1927" />  
      <PLAC_L2 Value="Hannover" />  
      <NOTE_L2 Value="Nordstadtkrankenhaus" />  
    </BIRT_L1>
    <DEATH_L1 Value="">  
      <DATE_L2 Value="21 JUN 1927" />  
      <PLAC_L2 Value="Mannheim" />  
      <NOTE_L2 Value="abends 21.03 Uhr" />  
    </DEAT_L1>
  </INDI_L0>

Diese Datei soll wie folgt umstrukturiert werden:
  <INDI_L0 OrigID="@I10@" >  
    <NAME_L1 Value="Kurt Andres" />  
    <SEX_L1 Value="M" />  
    <_UID_L1 Value="db4b4267-51e8-4f66-9272-29187e29b57c" />  
    <BIRT_L1 Value="">  
      <DATE_L2 Value="18 JUN 1927" />  
      <PLAC_L2 Value="Hannover" />  
    </BIRT_L1>
    <DEATH_L1 Value="">  
      <DATE_L2 Value="21 JUN 1927" />  
      <PLAC_L2 Value="Mannheim" />  
    </DEAT_L1>
    <NOTE_L1 Value="Geburt: Nordstadtkrankenhaus" />  
    <NOTE_L1 Value="Tod:abends 21.03 Uhr" />  
  </INDI_L0>

Ich suche einen möglichst einfachen Weg, um mit VB.NET oder C# die Notizen aus den Ereignissen zu löschen und stattdessen direkt an die Personen-Datensätze zu hängen. Es gibt auch Datensätze, bei denen die Notiz bei Geburt, bei Tod oder auch bei beiden Ereignissen fehlt.

Ich habe im Netz gelesen, dass mit LINQ solche Änderungen einfach umzusetzen wären, habe aber bisher damit keine Erfahrungen und auch bei XML ist dies mein erstes Vorhaben. Kann mir jemand auf die Sprünge helfen oder hat jemand ein gutes Tutorial, das auch für XML-Anfänger geeignet ist? Die Änderungen an den jeweiligen Texten in den Notizen sollte ich allein hinbekommen.

Vielen Dank im voraus,
M. Born

Content-Key: 621184

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

Printed on: April 16, 2024 at 16:04 o'clock

Member: Pjordorf
Pjordorf Nov 11, 2020 at 20:23:34 (UTC)
Goto Top
Hallo,

Zitat von @MarcoBorn:
ich habe eine XML-Datei mit ca.20.000 Datensätzen. Die haben folgende Grundstruktur:
Nicht eher eine (1) Datei und da drin dann deine ca. 20.000 Knoten?
https://www.google.com/search?q=Powershell+und+XML
https://www.google.com/search?q=XML+Editor

Gruß,
Peter
Member: MarcoBorn
MarcoBorn Nov 12, 2020 at 05:56:00 (UTC)
Goto Top
Hallo Peter,
ein XML-Editor hilft mir nicht weiter, da ich dort jede Änderung von Hand ausführen muss. Ich suche, wie schon geschrieben, nach einer Möglichkeit, die Änderungen mit Hilfe von C# oder VB.NET zu programmieren. Mit PowerShell kenne ich mich überhaupt nicht aus.

Viele Grüße,
M. Born
Mitglied: 146189
Solution 146189 Nov 12, 2020 updated at 08:40:02 (UTC)
Goto Top
Mach einfach einen XML-Transform mit XSLT face-wink, hier ein passendes Stylesheet für deine Änderungen:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
<xsl:output method="xml" indent="yes"/>  
<xsl:strip-space elements="*" />  

<xsl:template match="@*|node()">  
 <xsl:copy>
  <xsl:apply-templates select="@*|node()"/>  
 </xsl:copy>
</xsl:template>

<xsl:template match="//DEATH_L1|//BIRT_L1">  
 <xsl:copy>
  <xsl:apply-templates select="child::node()[not(self::NOTE_L2)]" />  
 </xsl:copy>
 <xsl:apply-templates select="NOTE_L2" />  
</xsl:template>

<xsl:template match="//DEATH_L1/NOTE_L2">  
  <NOTE_L1 Value="Tod:{@Value}" />  
</xsl:template>

<xsl:template match="//BIRT_L1/NOTE_L2">  
  <NOTE_L1 Value="Geburt:{@Value}" />  
</xsl:template>

</xsl:stylesheet>
Wie man per .NET eine Stylesheet-Transformation macht kannst du dann hoffentlich noch selbst googeln...
Member: MarcoBorn
MarcoBorn Nov 12, 2020 at 10:22:54 (UTC)
Goto Top
Hallo,
Dein Stylesheet funktioniert. Ich habe die Transformation mit folgendem Code umgesetzt:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
		Dim xslt As XslTransform = New XslTransform()
		Dim xmlfilename As String = "C:\temp\mydata.xml"  
		Dim xmloutput As String = "C:\temp\Export.xml"  
		Dim xmlstylesheet As String = "C:\temp\myStyleSheet_bearb.xsl"  

		xslt.Load(xmlstylesheet)

		Dim doc As XPathDocument = New XPathDocument(xmlfilename)
		Dim writer As XmlTextWriter = New XmlTextWriter(xmloutput, System.Text.Encoding.UTF8)

		xslt.Transform(doc, Nothing, writer)
		writer.Close()
		MsgBox("Fertig")  
	End Sub
Allerdings fehlen im Output sämtliche Zeilenumbrüche und Einrückungen, so dass der Inhalt nur schwer lesbar ist. Kann man das bei der Transformation beibehalten?

Vielen Dank,
M. Born
Mitglied: 146189
Solution 146189 Nov 12, 2020 updated at 10:53:35 (UTC)
Goto Top
Allerdings fehlen im Output sämtliche Zeilenumbrüche und Einrückungen, so dass der Inhalt nur schwer lesbar ist. Kann man das bei der Transformation beibehalten?
Klar, musst nur den XMLTextWriter dazu anweisen PrettyPrint zu machen face-wink
https://stackoverflow.com/questions/1123718/format-xml-string-to-print-f ...
Member: MarcoBorn
MarcoBorn Nov 12, 2020 at 11:32:12 (UTC)
Goto Top
Vielen Dank. Wie ich schon gechrieben hatte, ist XML völlig neu für mich. Aber jgetzt sieht das Ergebnis so aus, wie es sein soll.
Mitglied: 146189
146189 Nov 12, 2020 at 11:54:02 (UTC)
Goto Top
Ergebnis zählt face-smile
Member: MarcoBorn
MarcoBorn Nov 16, 2020 at 06:41:29 (UTC)
Goto Top
Guten Morgen,
leider ist mein Problem doch noch nicht final gelöst. Ich habe vereinzelt Fälle, bei denen die zu verschiebenden Knoten auch Unterknoten haben, z.B.
<INDI_L0 OrigID="@I10@" >  
    <NAME_L1 Value="Kurt Andres" />  
    <SEX_L1 Value="M" />  
    <_UID_L1 Value="db4b4267-51e8-4f66-9272-29187e29b57c" />  
    <BIRT_L1 Value="">  
      <DATE_L2 Value="18 JUN 1927" />  
      <PLAC_L2 Value="Hannover" />  
      <NOTE_L2 Value="Nordstadtkrankenhaus" >  
        <CONT_L3 Value ="Gewicht: 3,5 kg" />  
        <CONT_L3 Value ="Größe: 48 cm" />  
      </NOTE>
    </BIRT_L1>
    <DEATH_L1 Value="">  
      <DATE_L2 Value="21 JUN 1927" />  
      <PLAC_L2 Value="Mannheim" />  
      <NOTE_L2 Value="abends 21.03 Uhr" />  
    </DEAT_L1>
  </INDI_L0>
Wie müsste ich die Transformation ergänzen, damit diese Daten ebenfalls mit verschoben werden?

Vielen Dank,
M. Born