Handbuch:XML-Importdateimanipulation in CSharp

This page is a translated version of the page Manual:XML Import file manipulation in CSharp and the translation is 100% complete.

Überblick

Diese Seite zeigt, wie man das MediaWiki-Schema mit Visual Studio .NET C# nutzt, um eine MediaWiki-XML-Import-Datei im Code durch die Nutzung von objektorientierter Programmierung statt durch die direkte Arbeit an der rohen XML-Datei zu manipulieren.

Ein Anwendungsfall hierfür ist, dass du vielleicht eine Reihe von Seiten auf einer Wiki-Seite hast, die verändert werden müssen. Eine Möglichkeit, um dies zu tun, ist, sie in eine XML-Datei zu exportieren, dann die XML-Datei zu manipulieren und dann die XML-Datei wieder zu importieren. Natürlich solltest du dir sicher sein, dass andere Benutzer diese Dateien nicht in der Zeit zwischen Export und Import bearbeiten können. Für Seiten mit moderater Nutzung kann dieser Ansatz angemessen sein.

Schema

Wie in diesem abgekürzten Beispiel einer XML-Import-Datei unten gezeigt, befindet sich die schemaLocation der XML-Datei in https://www.mediawiki.org/xml/export-0.3.xsd:

<mediawiki xmlns="https://www.mediawiki.org/xml/export-0.3/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="https://www.mediawiki.org/xml/export-0.3/ https://www.mediawiki.org/xml/export-0.3.xsd" 
version="0.3" 
xml:lang="en">
  <siteinfo>...</siteinfo>
  <page>...</page>
  <page>...</page>
  <page>...</page>
</mediawiki>

Lade erstmal das MediaWiki-Schema unter https://www.mediawiki.org/xml/export-0.3.xsd herunter. Platziere die Datei in einem .NET-Projektordner und ziehe in Erwägung, die Datei in etwas intuitiveres wie MediaWikiExport.xsd umzubenennen. Mit dem Werkzeug xsd.exe von Visual Studio.NET kannst du eine .NET-Klassendatei basierend auf diesem Schema unter Verwendung dieses VS.NET-Kommandozeilenbefehls generieren:

xsd c:/inetpub/wwwroot/MyProject/MediaWikiExport.xsd /c

Dieses Kommando erzeugt eine Klassendatei namens MediaWikiExport.cs.

Klassendiagramm

Die automatisch generierte Klassendatei wird wie diese aussehen:

 
Automatisch generierte VS.NET-C#-Klassendatei basierend auf dem MediaWiki-Importschema


Schemendiagramm

Das Schema sieht dann so aus:

 
MediaWiki-Import-Datei-Schema


.NET-Projekt

Füge die Datei zu deinem .NET-Projekt wie ein Konsolenanwendungsprojekt hinzu, nachdem du deine neue automatisch generierte Klassendatei hinzugefügt hast.

In diesem Code-Ausschnitt siehst du Beispiele dafür, wie man mit der XML-Datei auf eine objektorientierte Weise arbeitet, statt das rohe XML zu parsen. Beachte, dass das Code-Beispiel unten für die Version 1.13.2 von MediaWiki genutzt wurde.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace WikiFileManipulation
{
    class Program
    {
        static void Main(string[] args)
        {
            // name of the exported wiki file
            string file = "ExportedWikiPages.xml";

            // instantiate MediaWikiType object
            MediaWikiType mw = new MediaWikiType();

            // Open XML file containing exported wiki pages
            System.Xml.XmlDataDocument xml = new System.Xml.XmlDataDocument();
            xml.Load(file);

            // Deserialize the XML file into the MediaWikiType object
            XmlSerializer serializer = new XmlSerializer(typeof(MediaWikiType));
            System.Xml.XmlNodeReader oReader = new System.Xml.XmlNodeReader(xml);
            mw = (MediaWikiType)serializer.Deserialize(oReader);

            // Loop through all the Pages in the MediaWikiType object
            foreach (PageType p in mw.page)
            {
                foreach (object o in p.Items)
                {
                    // Examine the RevisionType
                    if (o is RevisionType)
                    {
                        // Cast to RevisionType object
                        RevisionType r = o as RevisionType;

                        // if you increment "timestamp" by one minute, then you'll be able to re-import file
                        r.timestamp = r.timestamp.AddMinutes(1);

                        // Update the value of the "text" of the revision
                        // this is the page text
                        TextType text = r.text as TextType;
                        text.Value = text.Value.Replace("oldvalue", "newvalue");
                    }
                }
            }

            //serialize the updated object back to the original file with the corrections/additions
            System.IO.TextWriter writer = new System.IO.StreamWriter(file);
            serializer.Serialize(writer, mw);
            writer.Close();
        }
    }
}

Version mit C# 3.0

Hier ist das Beispiel für die Nutzung von Funktionen von C# 3.0, darunter Typinterferenz und ein Lambda-Ausdruck.

using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

namespace WikiFileManipulation {
    class Program {
        static void Main(string[] args) {

            // name of the exported wiki file
            var file = "ExportedWikiPages.xml";
 
            // Open XML file containing exported wiki pages
            var xml =new XmlDataDocument();
            xml.Load(file);
 
            // Deserialize the XML file into the MediaWikiType object
            var serializer = new XmlSerializer(typeof(MediaWikiType));
            var nodeReader = new XmlNodeReader(xml);
            var mw = (MediaWikiType)serializer.Deserialize(nodeReader);
            
            // Loop through all the RevisionType Items from each Page
            foreach (var r in mw.page.SelectMany(p=>p.Items.OfType<RevisionType>())) { 
                // increment the "timestamp" in order to re-import file
                r.timestamp = r.timestamp.AddMinutes(1);
 
                // Update each revision's text
                r.text.Value = r.text.Value.Replace("oldvalue", "newvalue");
            }
 
            // serialize the updates back to the same file
            var writer = new StreamWriter(file);
            serializer.Serialize(writer, mw);
            writer.Close();
        }
    }
}