11. juli 2004 - 11:07Der er
73 kommentarer og 1 løsning
Script: Fra XML til mySQL
Hej
Kan nogen af Jer hjælpe mig i gang med et script til at trække min XML file's data over i en mySQL database. Jeg har tidligere haft én til at lave dette vha. access, men dette script skulle gerne selv kunne foretage det... Men denne overførsel skulle gerne foretages hver uge, og kun indskrive nye produkter til MySQL databasen.
Der er ca. 50000 poster i databasen. Kan det laves i ASP elle ASP.net. 100 point, da scriptet skal være rigtig godt og med mange forbehold, som jeg måske også skal ha' hjælp til. :-)
-------- Jeg kunne forestille mig en lykke, der ligner denne:
Hent en post ind fra XML Ret evt. datoformat og lignende Føj udvalgte oplysninger ind i mySQL databasen Next -------
Du kan lave et dataset udfra din xml-fil, og klaske den direkte ned i din MySql-database. Jeg kan lave et lille simpelt eksempel til dig... Så kan du jo se om det er tilstrækkeligt. Jeg poster det her lidt senere.
Følgende skal lagres i db: - id - title - link - image (HVIS DER ER ET! IKKE SIKKERT ALTID) - artist - media - release_date (kun år, dvs. de første fire tal)
Hmm... Jeg er ikke den store ASP-helt, men jeg kan lige vise dig et meget simpelt .NET eksempel (C#), så kan du sige om du er frisk på at gå videre med det. Hvad siger du til det ?
Hehe... Nu kan du lige se her hvad der skal til for at hælde data fra en xml-fil og ned i en database. Jeg tror du vil synes at det ser tilstrækkelig enkelt ud til at du måske kunne være frisk. Jeg har benyttet MySql client fra ByteFx.
private MySqlDataAdapter CreateAdapter() { // opret forbindelse MySqlConnection con = new MySqlConnection("Persist Security Info=False;database=grafikeren;server=server;user id=user;Password=password");
// opret command - kommandobbyggeren kan lave resten udfra denne simple select MySqlCommand command = new MySqlCommand("select * from tbltarget", con); // opret adapter MySqlDataAdapter adapter = new MySqlDataAdapter(command);
// tilknyt commandbuilder - så sørger den for at generere insert og delete kommandoer MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(adapter);
// retur med adapteren return adapter; }
Bemærk at dette kun går godt fordi xml-en "passer" til tabellen.
Det er self. helt utilstrækkeligt, men jeg tænkte at det kunne give dig lidt .NET blod på tanden :o)
Jeg vil gerne gå videre med det således at det kan blive reelt brugbart for dig.
Hvis det er helt sort kan jeg godt flette et par af dine specifikke krav ind, så du kan se det i en lidt mere funktionel sammenhæng... Skal jeg gøre det ? (har du mulighed for at lægge en fuld xml-fil online, så jeg kan hente den et eller andet sted ?)
Det ser fint ud, men jeg kan intet C#, derfor kan jeg ikke gøre det færdigt... Desværre!
Hvis du kan gøre det mere brugbart, således at de forskellige felter i XML filen "omdirrigeres" til forskellige felter i mySQL'en. Kun nogle af dem skal gemmes. Image skal kun gemmes, hvis der står noget i XML filen.
Følgende felter skal overføres til mySQL, hvor felterne hedder det samme.
- id - title - link - image (HVIS DER ER ET! IKKE SIKKERT ALTID) - artist - media - release_date (kun år, dvs. de første fire tal)
Hvis du kan få scriptet til at virke rigtig godt, så vil jeg gerne betale dig et lille beløb, hvis du er interesseret. Husk at XML filen er på 50 mb og oplysninger i mySQL databasen ikke skal overskrives. Der skal kun føjes til.
Skulle lige se om jeg kunne finde en converter der kunne transmogriffe C# kode til VB-kode. Du kan finde den her : http://www.kamalpatel.net/ConvertCSharp2VB.aspx (Der er også et link til en version der kører offline)
Kan du optimere koden til denne tabel: CREATE TABLE `tblalbums` ( `Id` int(11) NOT NULL auto_increment, `Kunstner` text NOT NULL, `Album` text NOT NULL, `Genre` text, `Overall` varchar(4) NOT NULL default '', `Image` text NOT NULL, `Link` text NOT NULL, `Media` text NOT NULL, `Release` year(4) NOT NULL default '0000', `oensket` char(1) default '0', PRIMARY KEY (`Id`,`Id`), KEY `Kunstnere` (`Kunstner`(250),`Album`(100)) ) TYPE=MyISAM AUTO_INCREMENT=11 ;
Du skal kun indsætte i id, kunstner, album, image, link, media, release.
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls;
// indlæs data fra xml-fil sourceDataSet.ReadXml(XMLFILE);
// opret targetdataset TargetDataSet targetDataSet = new TargetDataSet();
// smid de ønskede værdier fra sourcedataset ind foreach(DataRow sourceDataRow in sourceDataSet.Tables["product"].Rows) { // opret et targetdatarow baseret på TargetTable DataRow targetDataRow = targetDataSet.Tables[TargetTable.TblTarget].NewRow();
// map data fra source til target targetDataRow[TargetTable.title] = sourceDataRow["title"]; targetDataRow[TargetTable.artist] = sourceDataRow["artist"]; targetDataRow[TargetTable.link] = sourceDataRow["link"]; targetDataRow[TargetTable.media] = sourceDataRow["media"]; targetDataRow[TargetTable.image] = sourceDataRow["image"]; targetDataRow[TargetTable.release_date] = sourceDataRow["release_date"].ToString().Substring(0,4);
// tilføj rækken til targetdataset targetDataSet.Tables[TargetTable.TblTarget].Rows.Add(targetDataRow); }
private MySqlDataAdapter CreateAdapter() { // opret forbindelse MySqlConnection con = new MySqlConnection(CONNECTIONSTRING);
// opret command - kommandobbyggeren kan lave resten udfra denne simple select MySqlCommand command = new MySqlCommand("select * from tbltarget", con);
// opret adapter MySqlDataAdapter adapter = new MySqlDataAdapter(command);
// tilknyt commandbuilder - så sørger den for at generere insert og delete kommandoer MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(adapter);
public class TargetDataSet : DataSet { public TargetDataSet() { this.DataSetName = "TargetDataSet"; this.Namespace = "grafikeren"; this.Tables.Add(new TargetTable()); } }
public class TargetTable : DataTable { public static string TblTarget = "tbltarget"; public static string ID = "ID"; public static string title = "title"; public static string link = "link"; public static string image = "image"; public static string artist = "artist"; public static string media = "media"; public static string release_date = "release_date";
De med optimering til din egen tabel... Det kan du bare gøre her :
public static string TblTarget = "tbltarget"; public static string ID = "ID"; public static string title = "title"; public static string link = "link"; public static string image = "image"; public static string artist = "kunstner"; public static string media = "media"; public static string release_date = "release_date";
Du retter f.eks. : public static string artist = "artist"; Til : public static string artist = "kunstner";
Jeps - der skal C# koden ligge, men mit projekt hedder Snips her, og det gør mit namespace så også. Snips.Grafikeren skal du rette til <dit projektnavn>.Grafikeren
Jeg er ikke med på hvad projektnavn er. Jeg har bare uploaded koden til min hjemmeside, hvor den skal køre. Jeg har fjernet koden Inherits (et eller andet).
Hvor skriver jeg tabellens navn ind? Jeg har ændret: MySqlCommand command = new MySqlCommand("select * from tblalbums", con);
Jeg har rettet alle synlige steder med connection og felternes navne. Den indsætter bare ikke noget.
Det er ikke helt sådan det fungerer. Hvis du skal lave rettelser i koden skal det kompileres efterfølgende, så vi bliver nødt til at gøre det på en anden måde. 2 min, så sender jeg lige et forslag.
Ok - jeg laver lige en komplet side, hvor du også kan vælge den fil du vil uploade, og så sørger jeg for at du kan indskrive din egen connectionstring. Men jeg bliver nødt til at sende dig et par dll-filer også. Ellers kan du ikke få det til at køre. Kan jeg sende det til en emailadresse (og i givet fald hvilken) ?
Nu skal jeg lige prøve at forstå det... Man kan altså ikke rette i koden efter at det er blevet spyttet ud af dit program? Så skal vi måske lige overveje et par ting. XML filen er som sagt MEGA stor, og det vil derfor tage lang tid at køre ind. XML filen ligger på nettet, men kan selvfølgeligt hentes ned. Sciptet skal nok køre på nettet, da jeg har XP home. Skal man så vælge at downloade XML filen først til egen computer ELLER hente den fra dens placering ude på nettet ELLER uploade XML filen til samme server, som scriptet? Ligemeget hvad, så vil scriptet tage lidt tid at udføre. Kan du lave et lille response efter udførelsen. Det kunne være meget praktisk at få at vide, hvor mange poster der er blevet kørt ind i databasen.
Hmm... lige en lille ting : `Image` text NOT NULL, `Link` text NOT NULL, `Media` text NOT NULL, `Release` year(4) NOT NULL default '0000',
Der står at Image ikke må være null og der er ikke nogen default, men du har også skrevet at det ikke er sikkert at der er et link til et billede. Er det korrekt ? og hvad skal jeg i givet fald sørge for at indsætte hvis der ikke er nogen henvisning til et billede i xml-filen ?
Men noget helt andet... Hvis det er sådan at du skal have noget der er færdigt, og at det skal fikses så det virker på dit eget web-hotel - uden at du skal pille ved koden - skal du nok oprette det som en opgave herude istedet. Det er jo ikke rigtig noget spørgsmål så :o)
nej... vidste ikke det var så omfattende. Men vi 2 kan vel godt behandle det som en opgave. :-)
Ved intet image, skal den ikke skrive noget i databasen. Den skriver standart "". Det virker fint. Den må bare ikke være "null".
Filen ligger et bestemt sted ude på nettet. Jeg kan desværre ikke skrive stedet her. Men jeg kan vel skrive det ind i filen ligesom connection koden.
Denne rettelse kan vi ligeså godt tilføje med det samme:
public class TargetTable : DataTable { public static string TblTarget = "tbltarget"; public static string ID = "Id"; public static string title = "Album"; public static string link = "Link"; public static string image = "Image"; public static string artist = "Kunstner"; public static string media = "Media"; public static string release_date = "Release";
Nej det har jeg ikke husket, men det er nok mere fordi du skrev sådan her :
"Husk at XML filen er på 50 mb og oplysninger i mySQL databasen ikke skal overskrives. Der skal kun føjes til."
Jeg forstod det sådan at der ikke skulle pilles ved de oplysninger der stod i basen i forvejen, men kun tilføjes nye rækker, men den har jeg så misforstået.
Jeg ønsker at starte på en helt frisk database. Derfor skal alle cd'er køres ind på en gang. Derefter skal der køre en update en gang om ugen, som føjer nye cd'er til. Gamle cd'er ændre ikke data, derfor skal oplysninger ikke rettes. Det er dog muligt at der bliver tilføjet et billede, men det er vist for meget bøvl at den også skal tjekke for det. Hvis den bare kun kører nye ind.
Det er sådan set ikke noget problem (altså den med billedet), men det er et problem at du har auto-inkrementering på id-kolonnen, når du i virkeligheden ønsker at bevare de id's der kommer fra xml-filen. Det var også med til at narre mig :o)
Nånej... jeg har jo allerede lagt det lidt højere oppe :o)
Der er dog lavet lidt ændringer til det, så det kører i en transaktion, og connectionstring, filnavn og mapning mellem xml-tabel og target kan angives i web.config.
Hvis der er nogle der gerne vil se det sidste kan i bare skrive her - så skal jeg nok lægge det ud.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.