Har nu knåpat ihop ett skript som läser in en XML-fil, uppdaterar med ny info och skriver tillbaka det till filen.
Tänkte ge mig in på lite snygg uppdelning av XML-funktioner, och skulle behöva lite styrning i mitt tänkande.
Det jag tänkt mig är att ha skapa ett skript för att uppdatera en XML-fil.
Jag hade tänkt mig att lägga själva parserfunktionen i en egen inkluderingsfil för att kunna använda mig av den vid olika utseende av XMLfiler.
Sen hade jag tänkt mig en andra inkluderingsfil där jag lägger de andra filspecifika XML-funktionerna för att läsa in TAGGAR , ID och DATA i en variabel och sedan skicka den till den första inkluderingsfilen för att skriva till samma fil, (också en funktion som är oberoende av utseende på XML-filen).
Den andra filen skall sedan inkluderas på skriptsidan där variablerna kommer från en FORM.
Tänkte detta vore ett bra tillfälle att ta en stor tugga ur OOP delen av PHP.
Just nu känns det som tuggan hamnat i fel strupe :) och jag undrar om det är någon vänlig själ som har lust att ge mig lite styrning i hur jag lägger upp det hela.
PHP-OOP är helt rätt tänkt, det gör det hela mycket snyggare och enklare. Jag har lite svårt att förstå hur du menar, men jag kan lägga lite tankar här:
Först och främst bör du modellera lite över vilka klasser du kan tänkas behöva, det görs bäst på vanligt papper med en blyertspenna. De klasser jag spontant kan tänka mig är följande:
XMLDoc
XMLElement
XMLAttribute
XMLDoc hanterar hela dokumentet, som innehåller element ( XMLElement ) som kan innehålla attribut, värden och andra element - men inte behöver göra det.
Metoder för de olika klasserna:
För XMLDoc:
void XMLDoc->createDoc( [ string filename ] ) // Skapar nytt dokument
void XMLDoc->openDoc( string filename ) // Öppnar befintligt dokument
void XMLDoc->saveDoc( [ string filename ] ) // Sparar dokumentet
XMLElement XMLDoc->getRoot()
void XMLDoc->append( XMLElement element ) // Lägger till ett XMLElement i slutet av dokumentet
För XMLElement:
void XMLElement->append( XMLElement element ) // Lägger till ett XMLElement i slutet av elementet
string XMLElement->xml() // Returnerar värde på elementet, kan vara andra element också
void XMLElement->value( string value ) // Sätter ett nytt värde på elementet
void XMLElement->addAttribute( XMLAttribute attribute ) // Lägger till ett attribut till elementet
XMLAttribute XMLElement->getAttribute( string attribute-name ) // Hämtar attribut-värde från angivet attribut
För XMLAttribute:
void XMLAttribute->setName( string name ) // Sätter ett namn på attributet
string XMLAttribute->getName() // Returnerar namnet på attributet
void XMLAttribute->setValue( string value ) // Sätter ett värde på attributet
string XMLAttribute->getValue() // Returnerar värdet på attributet
Självklart finns med många fler metoder som borde vara med, men lite får du tänka själv. ;)
Säg till om du behöver mer hjälp, det är ju rätt krångligt att skapa en bra fungerande XML-parser i PHP - jag har försökt. :)
Såg att du i en tidigare tråd frågade efter en fungerande XML-parser, inbyggd eller extern. Det finns ju alltid XML-parserfunktionerna i PHP, men de kan vara lite kluriga. Jag har nog ett fungerande exempel om du vill veta mer... Ska leta lite på hårddisken. Fråga! :)
Mitt första inlägg baserar sig på att jag använt mig av de inbyggda XML-parserfunktionerna i PHP, och det fungerar bra. Jag har dock all kod i samma fil.
De filer jag tänkt jobba med har en färdig elementstruktur + tillhörande attribut. Men för att kunna i framtiden addera stöd för uppdatering av andra elementstrukturer tänkte jag mig en uppdelning på följande sätt, och det är här jag undrar om jag tänker rätt
Det jag tänkte mig i detta stadium var att dela upp de olika funktionerna så att till exempel:
Inkluderingsfil 2. där jag tänkt lägga de elementspecifika funktionerna
startElement()
endElement()
characterData()
Dessutom funktioner som ärver från de funktioner som ligger i inkluderingsfil1.
Nu är detta väldigt basic, men jag hoppas du förstår var jag är på väg. Om jag vid ett senare tillfälle skulle vilja uppdatera en annan XML fil med annorlunda elementstruktur kan jag då använda mig av inkluderingsfil1 i den med.
Jag skulle alltså vilja kunna inkludera inkluderingsfil2 i ett skript, skicka filnamn, attribut och data och filen uppdateras med dessa variabler.
Nej, jag tycker inte att ditt uppdelningstänkande är åt fanders - utan åt andra hållet. Det låter bra, speciellt med att du ärver från en annan klass för att skapa statiska metoder. Men här tycker jag att det bör kunna förbättras... Går det inte att skapa dynamiska metoder startElement(), endElement() och characterData()? Det beror ju egentligen på hur komplex XML-strukturen är, men bör väl gå att komma runt? T.ex. att passa arrayer som attribut till någon metod som lagrar den i en instans-variabel i klassen.
Jag förstår mycket bättre nu, men ge gärna lite kod-exempel så kanske jag kan ge ännu mer hjälp. :)
Jag förstår ditt tankesätt med att även göra dynamiska metoder av elementhanterarna. Jag var inne på en skiss där jag tänkte mig "tomma" XML-dokument som fungerar som mallar för hur det förväntade dokumentet ser ut.
Eftersom jag är ute på okänd OOP-mark siktade jag dock i första läget på den "semi"-dynamiska uppdelningen jag beskrev tidigare :)
När det gäller kod är jag fortfarande på papper&penna stadiet, så det är inte så mycket att visa. Har du några generella class-kodsnuttar att studera tar jag dock emot dem med öppna armar
Fast med tomma XML-dokument som mallar får du också semi-dynamik, eftersom att du inte kan "möblera om" dem, så att säga. Just skrivningen av XML måste man väl hålla på det stadiet, men som jag förstod det ville du även läsa XML-dokument? Där kan man vinna på att skriva dynamiskt. Jag har tyvärr inga färdiga exempel på just det här, och jag ska iväg nu. Men i morgon borde jag kunna slänga ihop något av det jag tänker på, plus kanske lite mer som jag kommer på. Hoppas att du inte är så otålig nu... I'll be back... :)
Ok, nu har jag suttit och fifflat lite - och kommit fram till följande två klasser ( SPiNXML.txt ). Jag vet ännu inte om de fungerar, jag har ingen server med PHP så att jag kan testa, men jag skrev ihop en test-fil ( SPiNXML_TestPilot.txt ) som borde göra det jag vill. :)
Det här är alltså bara grunden, när du vill skriva statiskt får du skapa en till klass som fyller upp ett dokument med det du vill.
Hoppas nu att det var något sånt här du var ute efter.
anropas funktionen newTag(). Den funktionen är inte skriven och jag får inte till det riktigt med mina begränsade OOP kunskaper.
Jag försökte byta ut den mot den bortkommenterade raden men får då dels varningen:
Warning: First argument to array_push() needs to be an array in SPiNXML.inc on line 132
Och dels error:
Fatal error: Call to a member function on a non-object in SPiNXML.inc on line 32
Har inte klistrat in mer kod här eftersom all kod finns i SPiN:s bifogade filer.
Eftersom SPiN är och springer hinderbana :) kanske någon annan vänlig själ kan tipsa, annars får jag vänta tills SPiN får på sig permisuniformen nästa gång.
Ingen hinderbana? Ack ack, hoppas inte ryssen kommer :)
Laddade ner din nya fil och provade med den.
Det som händer då är:
I din testpilot anropar du en funktion addData() som jag tycker borde vara addContent().
Jag får dessutom felmeddelande: Att första argumentet till array_push() skall vara en array.
Det verkar inte som konstruktorn körs när jag anropar
$tag = new SPiNXMLTag();
Om jag deklarerar variabeln $tagTags som en array i klassdeklarationen får jag bort felmeddelandena.
Gör jag detta får jag felmeddelande i funktionen getAttributes().
Raden:
return $this->theAttributes;
Borde inte den funktionen returnera:
return $this->tagAttributes;
När gjort detta får jag felmeddelandet:
Call to undefined function createxml() in spinxml.inc on line 64
Uff, nu har jag suttit och pillat i filerna för att se om det blir bättre. Jag har säkert glömt något, eller skrivit något fel - kom ju hem idag och är trött. :x
Ta det lungt, efter en vecka i grönt tycker jag du skall luta dig tillbaka och softa :)
När det gäller dina filer såg jag vid en snabb överblick:
I första filen: Du har skapat två nya klasser.
class SPiNXMLAttributeList
class SPiNXMLAttribute
I den första har du koden:
$xmlAttribute = new SPiNXMLAttribute();
$xmlAttribute->start();
klassen SPiNXMLAttribute(); har ingen startfunktion för initiering.
Jag skall, när jag får lite mer tid titta nogrannare på koden för att se hur du tänker.
En fråga bara. Hur kommer det sig att du ändrat klasserna från att ha en konstruktor till att ha startfunktioner?
Det var bara för att det inte verkade som att konstruktorerna kördes, för att se om det fungerade. Det är mycket fult gjort, och visst kan man göra annorlunda - men det här var det enklaste alternativet.
Attribut-klasserna lade jag till bara för att göra det lite snyggare och lättare att förstå. Istället för att returnera en array med arrayer med attributnamn och attributvärde ( Se ex. 1 ) så använder jag nu en attributlista som lagrar attributobjekt som innehåller namn och värden ( Se ex. 2 ), där man snabbt kommer åt ett attributvärde via SPiNXMLAttributList::getByName(). Ex. 1