Just nu i M3-nätverket
Gå till innehåll

XSL / XML


php-ante

Rekommendera Poster

Jag har ett XML-dokument som ser ut som följer

<bills>
<bill><date>2002-12-31</date><amount>1000</amount></bill>
<bill><date>2003-01-31</date><amount>1400</amount></bill>
</bills>

 

Problemet är att jag vill m.h.a ett XSL skapa en textfil att skicka till extern leverantör. Det kan max finnas 15 <bills> och dessa skall vara separerade av ett ";" i textfilen.

 

Problemet är att jag vill fylla upp textfilen med 15 st ; om det inte finns tillräckligt många bills.

 

Jag vill alltså loopa igenom 15-count(bill) gånger... Någon som har ngt tips?

 

[inlägget ändrat 2003-01-23 14:04:12 av Andreas.NET]

[inlägget ändrat 2003-01-23 14:19:25 av Andreas.NET]

Länk till kommentar
Dela på andra webbplatser

Hmmm... Jag förstår inte riktigt var du vill komma.

Vill du omvandla en XML-fil till en CSV-fil (comma separated values)?

 

Det skulle underlätta om du skrev in lite kort hur du ville att resultatet skulle bli.

Det kan max finnas 15 <bills>
Menar du <bills> eller <bill>? Varje <bills> kan ju sedan innehålla flera <bill>.

 

Du säger att du vill göra det med en XSL-fil, men då har det ju inget med PHP att göra, då du behöver du ju ett externt program till det.

 

Hur hade du tänkt spara de övriga värderna i varje individuell <bill> i textfilen?

 

Min gissning är att du menar ungefär så här:

2002-12-31;1000

2003-01-31;1400

2003-02-28;1100

2003-03-31;1300

 

Stämmer det?

 

Länk till kommentar
Dela på andra webbplatser

Nej, snarare så här

<bills>
  <bill>
     <date>
     <amount>
  </bill>
  <bill>
     <date>
     <amount>
  </bill>
</bills>

 

Redigerat av moderatorn:

kundnummer;kundnamn;kundadress;billdate;billamount;billdate;

billamount;billdate,billamount;billdate;billamount;billdate;

billamount;billdate;billamount;billdate;billamount;billdate;

billamount

 

Förstår du? Varje kund kan alltså ha upp till 15 bill (som finns inom bills).

 

Om de inte har 15 <bill> så ska det se ut ungeför som:

 

Redigerat av moderatorn:

kundnummer;kundnamn;kundadress;billdate;billamount;billdate;

billamount;;;;;;;;;;;;;;

 

För att fyll upp fälten korrekt så skapas extra semikolon upp till 15.

 

 

 

 

[inlägget ändrat 2003-01-24 11:10:16 av TicoRoman]

Länk till kommentar
Dela på andra webbplatser

Om du använder dig av XSLT genom Sablotron så kan det kanske bli lite svårt att fylla i de sista semikolonen, (hrrmmm... undrar om man säger semikolonen?) detta eftersom du egentligen inte kan scripta innuti XSL dokumentet.

 

Det du skulle kunna göra är att skapa upp en XSL variabel som du plussar på för varje gång du itererar och en annan variabel säger att du vill ha 15 semikolon. Om inte iterationen uppfyller den andra variabeln så skriver du ut så många semikolon som behövs.

 

Ett annat sätt kan vara att skita i att använda XSLT genom Sablotron och istället leka med XPath/DOM. Jag har hittat en class som jag själv tycker sköter DOM grejer riktigt hyfsat. Då kan du ju faktiskt använda PHP för att se om det blev 15 iterationer eller inte. Classen hittar du här: http://sourceforge.net/projects/phpxpath/

 

Det tredje alternativet, som jag själv tycker är trevligt är att fixa så man kan scripta i XSL. En varning är dock på sin plats, detta tips tar mycket kraft av din server, men gör så att man faktiskt kan scripta innuti XSL filer. Lägg till detta i den funktion du har för att konvertera XML till XSL, innan själva transformeringen:

 

while(!(strpos($xslData, "<xsl:eval>") === false)) {
               $startMarker = "<xsl:eval>";
               $endMarker = "</xsl:eval>";

               $startPos = strpos($xslData, $startMarker);
               $endPos = strpos($xslData, $endMarker);

               ob_start();
               eval(substr($xslData, $startPos + strlen($startMarker), $endPos - $startPos - strlen($startMarker)));
               $evaluatedString = ob_get_contents();
               ob_end_clean();

               $xslData = substr($xslData, 0, $startPos).$evaluatedString.substr($xslData, $endPos + strlen($startMarker) + 1);
       }

 

Tänk dock på att detta tar mycket kraft av servern, och har du många besökare på sidan som genererar är det nog inget alternativ.

 

En extra varning

I det sista alternativet jag beslriver finns det en eval som exekverar den kod som hittas innuti XSLen. Se till så att ingen utomstående kan ändra vilken XSL som körs eftersom detta är en grym säkerhetsrisk

 

UPPDATERAT: Glömde visst att lägga till länken för XPath grejen... La även till en liten varning...

 

--

Some say I am crazy.. but the Voices in my head disagree...

 

 

[inlägget ändrat 2003-01-24 10:51:07 av Bj0rN]

Länk till kommentar
Dela på andra webbplatser

Ett annat alternativ är ju att använda reguljära uttryck.

Jag tror följande åstadkommer det du vill:

<?php
$xml = "<bills>
<bill><date>2002-12-31</date><amount>1000</amount></bill>
<bill><date>2003-01-31</date><amount>1400</amount></bill>
</bills>";

echo $kunnr . ";" . $kundnamn . ";" . $kundadr;
preg_match_all("/<bill>[[:space:]]*<date>([^<]*)<\/date>[[:space:]]*<amount>([^<]*)<\/amount>[[:space:]]*<\/bill>/mi", $xml, $bills);
for ($i = 0; $i < 15; $i++) {
echo ";";
if (!isset($bills[1][$i])) { echo ";"; continue; }
echo $bills[1][$i] . ";" . $bills[2][$i];
}

 

Länk till kommentar
Dela på andra webbplatser

Jag tar mig friheten att redigera inlägget så att inte layouten på eForum, för just denna tråd, förstörs.

 

Alla "uppdelade" rader kommer att tydligt markeras med fet röd text!

 

 

 

PHP-MODERATOR

 

 

 

[inlägget ändrat 2003-01-24 11:08:13 av TicoRoman]

Länk till kommentar
Dela på andra webbplatser

Tänkte bara tillägga att XSLT ska användas för att omvandla ett XML-dokument till ett annat XML-dokument, inte för att omvandla till andra format. I det här fallet verkar reguljära uttryck, eller helt enkelt sök/ersätt vara den smidigaste lösningen. Har man mer komplicerade XML-dokument kan man använda PHP:s XML-parser.

 

http://www.php.net/manual/en/ref.xml.php

 

 

Länk till kommentar
Dela på andra webbplatser

Varför skulle XSL bara användas för att skapa ett nyt XML dokument?? Det är ju helt inkorrekt då XSL används för att skapa WAP/WML, HTML, XHTML, XML och TEXT utifrån XML-dokument.

 

Jag vill helst INTE skripta med PHP inne i mina XSL då detta är en säkerhetsrisk...

 

Kan man inte loopa i XSL:en ett visst antal ggr med Sablotron som motor?

 

Länk till kommentar
Dela på andra webbplatser

Kan man inte loopa i XSL:en ett visst antal ggr med Sablotron som motor?
Jo, det borde gå. Jag håller med dig, XSL är till för att konvertera till vilket format som helst, och det borde gå att loopa i en XSL-fil.

 

Men då föreslår jag att du ställer den frågan i XML-forumet istället, då jag inte är tillräckligt insatt i det, och det då inte längre har med PHP att göra.

 

Annars föreslår jag att du använder min reguljära-uttryckslösning ovan. Det blir enklare, och snabbare skulle jag tro.

 

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...