Mads-b Skrevet 29. januar 2008 Skrevet 29. januar 2008 (endret) Jeg driver å mekker litt på et CMS jeg har bygd for lenge siden, og fant ut at det var en ide å bygge configfilene i XML, så jeg ikke trengte å skrive en parser for "hjemmelaget" kode. jeg sitter fast på et av områdene: Lagring av nye instillinger, hentes fra POST og skal legges inn i simpleXML-objektet. Strukturen er slik: <setting name ="limit"> <name>Tidsbegrensing på posting i sekunder. (Floodcontrol). Skriv 0 for å skru av.</name> <value type="input">120</value> </setting> Jeg har altså flere slike "settings" nedover.. Så looper jeg gjennom POST-verdiene, og finner ut at "value" verdien skal endres fra 120 til x. Den eneste henvisningen er at settingen heter "limit". Da har vi et problem: $xml->setting['limit']->value funker ikke! Det sier seg selv.. Jeg må påkalle setting[name==limit] på en eller annen måte.. Hvordan påkaller jeg en atributt i en tag på denne måten? $xml->setting[0]->value funker, men er utrygg om noen omrokkerer på taggene.. What to do? Endret 29. januar 2008 av Mads-b
Mads-b Skrevet 29. januar 2008 Forfatter Skrevet 29. januar 2008 hva er $value? tror ikke du skjønte problemstillingen..^^ print_r gir dette på en <setting> tag: 2] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => limit ) [name] => Tidsbegrensing pÃ¥ posting i sekunder. [value] => 120 ) Hadde det bare vært et setting-element, kunne jeg satt <value> med $xml->setting->value = 'x' Nå har det seg slik at det er flere av dem, og at de er ulike i det at de har hver sin name-attributt satt til noe unikt. Jeg trenger altså en kommando som kan sette "value" inni det ønskede setting-elementet, bare ved å oppgi attributtverdien og <value>-verdien.. Get it? Jeg sliter som bare det nå.. Kan ikke se noen måte å omforme XML'en på heller, uten å gjøre det desto mer komplisert..
luxus Skrevet 30. januar 2008 Skrevet 30. januar 2008 Du vil altså ha ut element(er) fra XML fila på bakgrunn av elementets atributt? Jeg tror du da enten må loope over settingselementene, og deretter sjekke atributtene med f.eks. attributes() på elementet. Eller, du kan bruke Xpath til å hente ut elementer med gitt atributt. Jeg har ikke så stor erfaring med dette selv, men tror at $elementerSomMatcher = $xml->xpath('//@name=limit'); gir deg et array med alle elementer som har atributt limit. $xml->xpath('//settings[@name=limit]'); Henter ut alle settings-elementene, med atributt limit. Men igjen, jeg har ikke brukt dette selv, så jeg er litt småusikker.
Mads-b Skrevet 30. januar 2008 Forfatter Skrevet 30. januar 2008 Xpath høres meget bra ut! Jeg får lese litt mer og finne ut hvordan jeg skal gjøre det, men xpath virker som løsningen om det finnes en elegant en Takker ^^
Mads-b Skrevet 30. januar 2008 Forfatter Skrevet 30. januar 2008 xpath skuffer.. Det er en return-funksjon. Jeg trenger en metode å putte variabler inn i XML-en min på, og $xml->xpath('//settings[@name=limit]') = $var; gir en interressant feilmelding. Hvordan gir jeg elementer med spesifikke atributter nye verdier?
grimjoey Skrevet 30. januar 2008 Skrevet 30. januar 2008 loop gjennom elementene og lag de på nytt. gjør endringer der du treffer attributtene du ønsker.
Mads-b Skrevet 30. januar 2008 Forfatter Skrevet 30. januar 2008 (endret) Fant ut at det var eneste løsning selv.. Masse unødvendig kode jeg kunne spart meg for. Her er snutten som leser inn XML-dokumentet, henter $_POST data og putter inn det som skal inn rett sted og lagrer filen.. (før noen hyler over usikrede POST-verdier, så er den saken fikset av en funksjon jeg trykker denne typen variabler gjennom) $i=0; while($setting = $confxml->setting[$i]) { //vi looper gjennom settingelementer $settingtype = $setting->value['type']; $settingname = $setting['name']; if($settingtype == 'input' || $settingtype == 'textarea') { //setter "input" instilling; enkelt og greit $confxml->setting[$i]->value = $_POST["$settingname"]; } if($settingtype == 'checkbox' || $settingtype == 'radio') { //vi looper radiubuttonelementer $n=0; while($subval = $setting->value->subval[$n]) { $subvalname = $subval['ans']; if(in_array($subvalname, $_POST["$settingname"])) $confxml->setting[$i]->value->subval[$n] = 1; else $confxml->setting[$i]->value->subval[$n] = 0; $n++; } } $i++; } $confxml->asXML($editedfile) OR die('<p>Kunne ikke lagre filen; har du husket CHMOD 777?</p>'); Åpen for andre løsninger.. ^^ Endret 30. januar 2008 av Mads-b
luxus Skrevet 30. januar 2008 Skrevet 30. januar 2008 (endret) xpath skuffer.. Det er en return-funksjon. Jeg trenger en metode å putte variabler inn i XML-en min på, og $xml->xpath('//settings[@name=limit]') = $var; gir en interressant feilmelding. Hvordan gir jeg elementer med spesifikke atributter nye verdier? Ja, Xpath er en return funksjon. Den returnerer et sett med noder du kan jobbe på. "$xml->xpath('//settings[@name=limit]') = $var;" er en ny kodekonstruksjon jeg ikke har sett før Men dette fikk meg til å teste litt selv. Kode jeg skrev er som følger: <?php print "\n"; $xmlTxt = <<<EOXML <settings> <setting name="limit"> <name>limit</name> <value type="input">120</value> </setting> <setting name="limit"> <name>limit2</name> <value type="input">110</value> </setting> <setting name="test"> <name>testelement</name> <value type="input">12</value> </setting> </settings> EOXML; $xml = new SimpleXMLElement($xmlTxt); print "Looper over elementer i setings, med atributt limit.. Setter samtidig value-elementet til 50 etter å ha skrevet det ut:\n"; foreach ( $xml->xpath('//setting[@name="limit"]') as $setting ) { print "{$setting->value}\n"; $setting->value = 50; } print "Kjører samme loop igjen, og skriver ut for å bekrefte at verdiene er endret:\n"; foreach ( $xml->xpath('//setting[@name="limit"]') as $setting ) { print "{$setting->value}\n"; } print "\n\n"; ?> Denne koden gir output: php test.php Looper over elementer i setings, med atributt limit.. Setter samtidig value-elementet til 50 etter å ha skrevet det ut: 120 110 Kjører samme loop igjen, og skriver ut for å bekrefte at verdiene er endret: 50 50 Håper dette kan hjelpe :-) Endret 30. januar 2008 av luxus
Mads-b Skrevet 2. februar 2008 Forfatter Skrevet 2. februar 2008 (endret) Aha.. skjønner nå.. Men jeg skrev noe i halvsøvne, og koden er logisk, ingen feilmeldinger, men hvorfor fungerer det ikke? Tingen er at enkelte <value>-tagger har et flertalls <subval>-tagger. Disse representerer radiobuttons og checkbokser når jeg endrer filene via en hjemmelagd configfil-editor.. når jeg sender verdiene til scriptet som $_POSt-verdier, blir de snappet opp av denne..: foreach($confxml->setting as $setting) { //vi looper gjennom settingelementer $settingtype = $setting->value['type']; $settingname = $setting['name']; if($settingtype == 'input' || $settingtype == 'textarea') //setter "input" instilling; enkelt og greit $setting->value = $_POST["$settingname"]; if($settingtype == 'checkbox' || $settingtype == 'radio') { //vi looper radiubuttonelementer foreach($setting->value->subval as $subval) { $subvalname = $subval['ans']; if(in_array($subvalname, $_POST["$settingname"])) $subval = 1; else $subval = 0; } } syntaksen i XML er noe ala <setting name="revote"> <name>Kan brukere stemme flere ganger?</name> <value type="radio"> <subval ans="ja">0</subval> <subval ans="nei">1</subval> </value> og syntaksen i POST er vanlig checkbox-system, med an array, som ser ca. slik ut array [revote] { [0] ja } Kun valgt alternativ blir derfor med i POST-systemet.. Hvorfor funker ikke koden min? INput-delen funker, det er radiobuttons som ikke går. Ingen feilmeldinger. Går det ikke an å dele opp nodes i nye nodes? Endret 2. februar 2008 av Mads-b
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå