[PHP5/OO/XML/XSL] Werkwijze/logica

Pagina: 1
Acties:

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Ik zit met zo'n titel natuurlijk op /13.5, maar ik denk dat hier wat meer ervaring/kennis zit op het punt waar ik mee zit. If not, excuse me & move me :)

Ik maak momenteel een soort CRM, waarmee ik in eerste instantie klantgegevens wil beheren. Tegelijkertijd wil ik mijn skills op het gebied van PHP5/OO en XML/XSL een upgrade geven.

Hier fragmenten uit mijn code (we hebben het hier uiteindelijk gewoon over 1 customer):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Customer {
    private $customer_id;
    private $surname;
    private $address;
    function __construct() {
        
        $this->customer_id = -1;
        $this->surname = '';
        $this->address = '';

        $this->arrMetaData['customer_id'] = array('type' => 'int',      'required' => true);
        $this->arrMetaData['surname'] = array(    'type' => 'string',   'required' => true);
        $this->arrMetaData['address'] = array(    'type' => 'string',   'required' => false);
    }
}


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$objCustomer = new Customer();
// Haal Customer data uit DB als er een id is meegegeven
// Dit gebeurt ook als er een form gePOST is, dan wordt de data uit $_POST gehaald
if(isset($_GET['customer_id']) && $_GET['customer_id'] > 0) {
    $objCustomer->load($_GET['customer_id']);
}

$objXMLDocument = new XMLDocument();

$objXSLProc = new xsltProcessor;
$objXSLProc->importStyleSheet(DomDocument::load('xsl/edit_customer.xsl'));
echo $objXSLProc->transformToXML($objXMLDocument);

Met deze objecten en methods kan ik netjes een XML document maken, die er bijvoorbeeld als volgt uitziet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<root>
  <data type="customer">
    <customer>
      <customer_id>1</customer_id>
      <surname>Jansen</surname>
      <address>Straatlaan 1</address>
    </customer>
  </data>
  <required>
    <customer_id/>
    <surname/>
  </required>
  <error>
    <surname/>
  </error>
</root>

Of zo:
code:
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
<root>
  <data type="customer">
    <customer>
      <customer_id required="1" error="0">1</customer_id>
      <surname required="1" error="1">Jansen</surname>
      <address required="0" error="0">Straatlaan 1</address>
    </customer>
  </data>
</root>

Het <required>-element (of attribuut) wordt aangemaakt op basis van de array in de constructor van de Customer-class. Het leek mij handig dit zo te kunnen centraal te kunnen beheren (er kan zo evt. nog meer metadata toegevoegd worden).

Het <error>-element (of attribuut) wordt alleen aangemaakt als er een form gepost is (de post-data wordt wel door een andere class gehaald om te kijken of deze valide is). Op basis hiervan is het dan de bedoeling dat er in het XSL document bijvoorbeeld een attribuut class="error" aan dat veld wordt toegevoegd.

Hopelijk is het so far nog een beetje normaal wat ik bedacht heb.

En dan komt het XSL-gedeelte. In een ander topic probeer ik al wat uit, wat niet echt wil lukken. De oplossing die Blues daar geeft zou wel de mooiste zijn denk ik, maar XSLT 2.0 met PHP5 gaat niet zo makkelijk. Aan de andere kant heb ik een makkelijkere oplossing bedankt, maar die is minder flexibel: namelijk een <xsl:for-each> voor elk <customer>-element gebruiken en aan de hand van de attributen die "required" en "error" zaken afhandelen (maar ook het soort input (text, checkbox) kan bij die metadata). Zie bijvoorbeeld het * bij het "required" veld.
HTML:
1
2
3
<input type="hidden" name="customer_id" value="1"></input>
<label for="surname">Achternaam: *<input type="text" name="surname" value="Jansen"></input>
<label for="address">Adres:<input type="text" name="address" value="Jansen"></input>

Maar dat betekent dat alle form-velden gewoon na elkaar komen in de HTML output. Dit kan wel eens onwenselijk zijn natuurlijk.

Heel verhaal, eigenlijk komt het op het volgende neer: wat is een gangbare en intelligente manier om dit op te lossen? Doe ik het goed met die Class > XML > HTML?

In ieder geval bedankt voor het lezen _/-\o_

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Je tweede XML-versie maakt wel meer sense dan je eerste. Verder ziet het er redelijk okay uit. Wat je nog zou kunnen doen is een gedeelte van de XML al genereren vanuit je Customer-object.

Rustacean


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Manuzhai schreef op vrijdag 20 mei 2005 @ 08:45:
Je tweede XML-versie maakt wel meer sense dan je eerste.
Ja dat is wel logisch, de eerste had ik initieel.
Wat je nog zou kunnen doen is een gedeelte van de XML al genereren vanuit je Customer-object.
Dat is wel een goed idee. Als ik later bijvoorbeeld een factuur aan een klant koppel, wordt de XML gewoon uitgebreid met een <invoice>-element.

Graag zou ik nog reacties zien over de laatste stap van XML+XSL > HTML. Hoe pakken jullie zoiets aan? Hoe genereren jullie zo'n pagina op basis van een XML document?

[ Voor 4% gewijzigd door X-Lars op 20-05-2005 12:45 ]


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
*kick* :)

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 11:44

Tux

Je kan Sablotron gebruiken om XML+XSL naar HTML om te zetten.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Tux schreef op maandag 23 mei 2005 @ 11:43:
Je kan Sablotron gebruiken om XML+XSL naar HTML om te zetten.
Wat heeft Sablotron nu voor meerwaarde boven de XSL extensie van PHP5?
Description: Sablotron is a fast, compact and portable XML toolkit implementing XSLT 1.0, DOM Level2 and XPath 1.0.

  • r0bert
  • Registratie: September 2001
  • Laatst online: 26-04 17:38
Wat moet er op mijn server draaien om gebruik te kunnen maken van
code:
1
XMLDocument
?
Er staat op mijn server wel DOMXml, maar als ik doe
code:
1
$oXML = new XMLDocument();
of
code:
1
$oXML = new xml_parser_create();
krijg ik een error.. ?
e: ik kan dus niet zelf bij die server.. shared hosting etc..


mijn phpinfo
domxml
DOM/XMLenabled
DOM/XML API Version20020815
libxml Version20510
HTML Supportenabled
XPath Supportenabled
XPointer Supportenabled

[ Voor 66% gewijzigd door r0bert op 23-05-2005 21:52 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
X-Lars schreef op vrijdag 20 mei 2005 @ 12:45:
Graag zou ik nog reacties zien over de laatste stap van XML+XSL > HTML. Hoe pakken jullie zoiets aan? Hoe genereren jullie zo'n pagina op basis van een XML document?
Ik doe eigenlijk steeds minder met XSL wat dat betreft, hooguit wat losse XHTML chunks bij elkaar vegen (aggregeren met een mooi woord). M'n hoofdtemplate, waar alle statische elementen van een pagina al in staan, is al netjes XHTML (is een prima formaat voor het generiek structureren van gegevens, dus waarom zelf iets bedenken en later heel duur ombouwen naar XHTML met XSL). Deze gaat hand in hand met een (abstract) class Page (extends DomDocument). Deze Page kan afhankelijk van het doel van de pagina geextend worden met allerlei extra functionaliteit. Zo is er een class Form extends Page etc.

Daarnaast heb ik een class Transform (extends Xsltprocessor) die een XSL file in kan laden en waarvan de projectspecifieke subklasses parameters in de XSLT kun zetten e.d. Het hele zaakje kan dynamisch aan elkaar gehangen worden en het geheel dus transformeren naar (X)HTML.

De DAL (data access layer) laat ik door Propel in elkaar sjeesen, die bv op basis van een simpel stukje XML complete persistance classes uitpoept, vergelijkbaar met jouw Customer maar dan met een hele berg gave functionaliteit.

Voor het ombouwen van de PHP objecten naar XHTML kan ik de door Propel gegenereerde klasses uitbreiden met bijvoorbeeld een method Customer::toXHTML(). Dit doe ik netjes met de PHP5 DOM, geen gebroddel met strings aan elkaar plakken:

BinaryQuestion::toDefinitionList()
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public function toDefinitionList(DomDocument $doc) {
        
        $dl = $doc->createElement("dl");
        $dt = $doc->createElement("dt");
        $dd_true = $doc->createElement("dd");
        $input_true = $doc->createElement("input");
        $label_true = $doc->createElement("label");
        $dd_false = $doc->createElement("dd");
        $input_false = $doc->createElement("input");
        $label_false = $doc->createElement("label");
        
        $dt_text = $doc->createTextNode($this->getBody());
        $label_true_text = $doc->createTextNode($this->getLabelTrue());
        $label_false_text = $doc->createTextNode($this->getLabelFalse());
        
        $id = $this->getId();
        $id_true = "binaryanswer_".$id."_true";
        $id_false = "binaryanswer_".$id."_false";
        $name = "binaryanswer_".$id;
        
        $dl->setAttribute("id", $this->getPosition()+1);
        $dl->setAttribute("class", "binaryquestion");
        
        $input_true->setAttribute("type", "radio");
        $input_true->setAttribute("id", $id_true);
        $input_true->setAttribute("name", $name);
        $input_true->setAttribute("value", true);
        $label_true->setAttribute("for", $id_true);     
        $input_false->setAttribute("type", "radio");        
        $input_false->setAttribute("id", $id_false);
        $input_false->setAttribute("name", $name);
        $input_false->setAttribute("value", false);
        $label_false->setAttribute("for", $id_false);
        
        $dt->appendChild($dt_text);
        $label_true->appendChild($label_true_text);
        $label_false->appendChild($label_false_text);
        $dd_true->appendChild($input_true);
        $dd_true->appendChild($label_true);
        $dd_false->appendChild($input_false);
        $dd_false->appendChild($label_false);
        $dl->appendChild($dt);
        $dl->appendChild($dd_true);
        $dl->appendChild($dd_false);
        
        return $dl;
    }


In m'n subclass van Page wordt een XHTML template met daarin een leeg formulier ingeladen, een query uitgevoerd mbv Criteria, op het resultaat bovenstaande functie aangeroepen en het resultaat erin gehangen:

SurveyServer::loadTheme()
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    /** 
    * @return void
    */
    private function loadTheme() {
        $this->load(TEMPLATE_PATH."/theme.xhtml");
        
        $c = new Criteria();        
        $c->addJoin(QuestionPeer::THEME_ID, ThemePeer::ID);             

        $c->addAnd($c->getNewCriterion(ThemePeer::SURVEY_ID, $this->session->getSurveyId(), Criteria::EQUAL));
        $c->addAnd($c->getNewCriterion(ThemePeer::ID, $this->session->getThemeId(), Criteria::EQUAL));
        $c->addAscendingOrderByColumn(QuestionPeer::POSITION);
        
        $questions = QuestionPeer::doSelect($c);
        
        $form = $this->getHook("//form");
            
        if(count($questions) > 0) {  
            
            try {
                $submit = $this->getHook("//form//input[@type='submit']");
            }
            catch(SurveyException $se) {
                $submit = null;
            }
            foreach($questions as $question) {
                $form->insertBefore($question->toDefinitionList($this), $submit);
            }
            
            $input_guid = $this->createElement("input");
            $input_guid->setAttribute("type" , "hidden");
            $input_guid->setAttribute("name" , "participator_guid");
            $input_guid->setAttribute("id"   , "participator_guid");
            $input_guid->setAttribute("value", $this->participator->getGuid());
            $form->insertBefore($input_guid, $submit);
            
            $h1      = $this->getHook("//h1");
            $theme   = $question->getTheme();
                
            $h1_text = $this->createTextNode("Thema: ".$theme->getName());
            $h1->appendChild($h1_text);
        }
        else {
            throw new SurveyException("Current theme has no questions.");
        }   
    }


De XSL trap daarna doet in geval van bovenstaande code helemaal niets meer, slechts een dikke copy-of op het hele zwikkie. In normale omstandigheden (deze XHTML werd aan een Flash client gevoerd en was alleen voor het gemakkelijk devven XHTML compatible) kan ik me voorstellen dat er nog een menuutje bij word geveegd o.i.d. Dat kan via deze methode maar wellicht handiger vanuit de XSL met de document functie.

Formvalidatie verwerk ik niet in m'n XHTML tussenlaag, afgezien van wat "hooks" in de vorm van <span id="errorFieldName" class="formError"></span>, alwaar ik eventuele validatiefouten in kan hangen wanneer nodig. De rest van de validatie wordt gedefineerd in de XML die je aan propel-generator voert alvorens die duizenden regels code uitbraakt, inclusief (customizable) validatie code. Een stukje van zo'n XML file kan er zo uitzien (validatietags onderaan):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<table name="book" description="Book Table">
    <column
      name="id"
      required="true"
      primaryKey="true"
      autoIncrement="true"
      type="INTEGER"
      description="Book Id"/>
    <column
      name="title"
      required="true"
      type="VARCHAR"
      size="255"
      description="Book Title"/>
    <column
      name="isbn"
      required="true"
      type="VARCHAR"
      size="24"
      phpName="ISBN"
      description="ISBN Number"/>
    <column
      name="publisher_id"
      required="false"
      type="INTEGER"
      description="Foreign Key Publisher"/>
    <column
      name="author_id"
      required="false"
      type="INTEGER"
      description="Foreign Key Author"/>    
    <foreign-key foreignTable="publisher" onDelete="SETNULL">
      <reference
        local="publisher_id"
        foreign="id"/>
    </foreign-key>
    <foreign-key foreignTable="author" onDelete="SETNULL">
      <reference
        local="author_id"
        foreign="id"/>
    </foreign-key>
    <validator column="title" translate="none">
      <rule
        name="unique"
        message="Book title already in database." />      
      <rule
        name="minLength"
        value="10"
        message="Book title must be more than ${value} characters long."/>
    </validator>
  </table>


Ben er wel tevreden mee, behalve met de snelheid van Propel, dat kan wellicht allemaal een stuk efficienter. Maar voor veel read-only pagina's kun je daar weer een cache tegenaan plakken. Ben ik alleen nog niet aan toegekomen :)

[ Voor 11% gewijzigd door Genoil op 23-05-2005 23:44 ]


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Genoil O+
Genoil schreef op maandag 23 mei 2005 @ 23:42:
[...]


Ik doe eigenlijk steeds minder met XSL wat dat betreft, hooguit wat losse XHTML chunks bij elkaar vegen (aggregeren met een mooi woord). M'n hoofdtemplate, waar alle statische elementen van een pagina al in staan, is al netjes XHTML (is een prima formaat voor het generiek structureren van gegevens, dus waarom zelf iets bedenken en later heel duur ombouwen naar XHTML met XSL).
Die XSL komt er toch sowieso nog aan? Zo duur is het dan toch niet om in je XSL a.h.w. statische (X)HTML te hebben staan. Anyway, ik vind XML wel goed als basis, want dan kan ik er later ook makkelijk bijvoorbeeld een factuur in PDF mee maken.
Deze gaat hand in hand met een (abstract) class Page (extends DomDocument). Deze Page kan afhankelijk van het doel van de pagina geextend worden met allerlei extra functionaliteit. Zo is er een class Form extends Page etc.
Hier zie ik het nut wel van in, ik denk dat ik dat vanzelf wel heel gauw nodig ga hebben :)
[...]

De DAL (data access layer) laat ik door Propel in elkaar sjeesen, die bv op basis van een simpel stukje XML complete persistance classes uitpoept, vergelijkbaar met jouw Customer maar dan met een hele berg gave functionaliteit.
Propel ziet er leuk uit! Heb er even naar gekeken en het is een interessant concept. Maar uiteindelijk ben ik toch wel geneigd alles zelf te willen doen. Ja, ik weet het, moet ik niet altijd doen ;)
Voor het ombouwen van de PHP objecten naar XHTML kan ik de door Propel gegenereerde klasses uitbreiden met bijvoorbeeld een method Customer::toXHTML(). Dit doe ik netjes met de PHP5 DOM, geen gebroddel met strings aan elkaar plakken:

BinaryQuestion::toDefinitionList()
PHP:
1
...


In m'n subclass van Page wordt een XHTML template met daarin een leeg formulier ingeladen, een query uitgevoerd mbv Criteria, op het resultaat bovenstaande functie aangeroepen en het resultaat erin gehangen:

SurveyServer::loadTheme()
PHP:
1
...
Krijg je dan alle form-elementen direct achter/onder elkaar? Dit was één van de dingen waar ik zelf mee zat. Stel, je wilt een <hr/> ergens tussen twee <input>-elementen in, hoe doe je dat dan?
[...]
Formvalidatie verwerk ik niet in m'n XHTML tussenlaag, afgezien van wat "hooks" in de vorm van <span id="errorFieldName" class="formError"></span>, alwaar ik eventuele validatiefouten in kan hangen wanneer nodig.
Dat voldoet niet aan mijn semantiek-purisme :P
De rest van de validatie wordt gedefineerd in de XML die je aan propel-generator voert alvorens die duizenden regels code uitbraakt, inclusief (customizable) validatie code. Een stukje van zo'n XML file kan er zo uitzien (validatietags onderaan):
code:
1
...
Toch wel handig dat je met 1 XML zowel de DB als de validatie regelt, maar ik kan me goed voorstellen dat Propel teveel overhead veroorzaakt. Z'n kracht (alles wordt voor je geregeld) wordt daarmee ook z'n zwakte (snelheid).

Bedankt voor je uitleg! Dit bedoelde ik nou, misschien zijn er nog anderen die mij zoiets op zijn/haar wijze kunnen voorleggen?

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
X-Lars schreef op dinsdag 24 mei 2005 @ 00:47:
Genoil O+

[...]

Die XSL komt er toch sowieso nog aan? Zo duur is het dan toch niet om in je XSL a.h.w. statische (X)HTML te hebben staan. Anyway, ik vind XML wel goed als basis, want dan kan ik er later ook makkelijk bijvoorbeeld een factuur in PDF mee maken.
Mja ik zie (hier) wel eens mensen die dit soort dingen doen:
code:
1
2
3
4
5
6
<boek>
    <id>1</id>
    <titel>blaat</titel>
    <isbn>123</isbn>
    <synopsis>blaat blaat</synopsis>
</boek>

Op zich helemaal niks mis mee, maar dat komt dan zo 1 op 1 uit de goeie ouwe MySQL database, waarna ze er met een XSL slag dit van maken:
code:
1
2
3
4
<div id="boek_1" class="boek">
    <h3>blaat</h3>
    <p>blaat blaat</p>
</div>

Ook helemaal niet verkeerd. Maar omdat ik in mijn systeempje al generieke objecten heb die ik terug krijg uit de database, vind ik het niet zinvol daar nog een extra generieke XML laag tussen te bouwen. Het PDF argument zit wel wat in, maar ik zou kunnen aanvoeren dat je net goed XHTML naar PDF kunt ombouwen met XSL. En wat ik doorgaans hoor van XSL:FO (= een bitch!), is het veel gemakkelijker dat te mijden en iets als PDFLib te gebruiken, direct op de objecten-laag.

De code uit m'n post komt uit een projectje waar je enquetes kon maken waarvan de antwoorden in de database kwamen. De enquete zelf stond ook in de database, maar de blauwdruk voor elke enquete deed ik wel in custom XML, omdat dat gewoon veel gemakkelijker en overzichtelijker was, met <survey> , <theme> en <question> elementen. Het CMSje voor het bewerken van deze files had wel een uitgebreide survey2cms.xsl, die er een groot HTML formulier van bakte voor het bewerken van de de enquete. Ik gebruikte dan weer de PHP5 DOM om deze survey.xml files om te bouwen naar een runtime versie in Propel objecten.
Propel ziet er leuk uit! Heb er even naar gekeken en het is een interessant concept. Maar uiteindelijk ben ik toch wel geneigd alles zelf te willen doen. Ja, ik weet het, moet ik niet altijd doen ;)
Ik denk dat er zeker ook voordelen zijn om het zelf te doen. Je hebt bijvoorbeeld veel meer controle over je eigen code zodat je gemakkelijk kunt optimaliseren. En eigenlijk vind ik de database-abstractie laag van Propel (Creole) niet zo heel interessant, ik werk toch op MySQL 9 van 10 keer. Wellicht ga ik een keer als ik tijd heb graven in die Propel code om dat er voor de lol eens uit te slopen om te kijken of het wat oplevert :). Maarja dat 'neiging om alles zelf te willen doen' is natuurlijk onzin. Ik bedoel, je gebruikt ook lekker 'DomDocument' en omdat die in PHP meegecompiled is vind je dat niet 'gebruik maken van'. Als het een beetje meezit duurt het ook niet zo lang meer eer PDO (PHP Data Objects) standaard meegebakken wordt :) (overigens PDO !~ Propel, eerder PDO ~ Creole)
[...]

Krijg je dan alle form-elementen direct achter/onder elkaar? Dit was één van de dingen waar ik zelf mee zat. Stel, je wilt een <hr/> ergens tussen twee <input>-elementen in, hoe doe je dat dan?
Met DomNode::appendChild en DomNode::insertBefore kun je alles. In dit geval kun je als semantiek purist natuurlijk geen hr ergens binnen een dl gaan proppen ;). Maar misschien dat je bedoelt dat in deze fase van het proces de hr er nog niet tussen kan omdat ie er soms wel moet en soms niet. Dan zou ik die er toch liever in de XSLT-trap tussen zetten. Ook kun je de functie zo opbouwen dat wat ik de "hook" noem (het element waar het resultaat van de functie aangehangen wordt) als extra argument in de functie binnenkomt, zodat je binnen de functie al een parent node hebt waaraan dingen gehangen kunnen worden.
Toch wel handig dat je met 1 XML zowel de DB als de validatie regelt, maar ik kan me goed voorstellen dat Propel teveel overhead veroorzaakt. Z'n kracht (alles wordt voor je geregeld) wordt daarmee ook z'n zwakte (snelheid).
We zijn nu met een project bezig waarin we wel Propel gebruiken voor het CMS en een cron-job die pak em beet 1 keer per 5 minuten gedraaid wordt omdat daarin nou eenmaal lastige dingen gedaan moeten worden en er toch weinig users voor zijn, terwijl we aan de front-end met hele lichte direct-op-de-mysql en geen OOP werken.
Bedankt voor je uitleg! Dit bedoelde ik nou, misschien zijn er nog anderen die mij zoiets op zijn/haar wijze kunnen voorleggen?
zijn 8)

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Genoil schreef op dinsdag 24 mei 2005 @ 09:40:
[...]

Ook helemaal niet verkeerd. Maar omdat ik in mijn systeempje al generieke objecten heb die ik terug krijg uit de database, vind ik het niet zinvol daar nog een extra generieke XML laag tussen te bouwen. Het PDF argument zit wel wat in, maar ik zou kunnen aanvoeren dat je net goed XHTML naar PDF kunt ombouwen met XSL. En wat ik doorgaans hoor van XSL:FO (= een bitch!), is het veel gemakkelijker dat te mijden en iets als PDFLib te gebruiken, direct op de objecten-laag.
Die extra XML is nog wel eens overbodig, maar ik doe hem er nu wel tussen, omdat ik het hele concept eens aan het werk wil hebben. Maar
code:
1
2
3
4
5
<input name="surname" id="surname">
    <xsl:attribute name="value">
        <xsl:value-of select="/webprocrm/data/customer/surname"/>
    </xsl:attribute>
</input>

heeft natuurlijk weinig voordelen t.o.v.
code:
1
<input name="surname" id="surname" value="<?=$customer['surname'];?>">

dus daar hoef ik het niet voor te doen :p
[...]
Maarja dat 'neiging om alles zelf te willen doen' is natuurlijk onzin. Ik bedoel, je gebruikt ook lekker 'DomDocument' en omdat die in PHP meegecompiled is vind je dat niet 'gebruik maken van'.
[...]
Ja, dat is idd een dubieuze opmerking. Maar ik heb bijvoorbeeld ook wel een eigen Database-class gemaakt (i.p.v. van ADOdb gebruik te maken). Voor PDF gebruik ik dan wel een andere class, omdat die niet (gratis) bij PHP zit. Dus mijn opmerking was meer in de trant van "als het met (een extensie van) PHP kan, dan heb ik de neiging het zelf te doen". :)
[...]

Met DomNode::appendChild en DomNode::insertBefore kun je alles. In dit geval kun je als semantiek purist natuurlijk geen hr ergens binnen een dl gaan proppen ;). Maar misschien dat je bedoelt dat in deze fase van het proces de hr er nog niet tussen kan omdat ie er soms wel moet en soms niet. Dan zou ik die er toch liever in de XSLT-trap tussen zetten. Ook kun je de functie zo opbouwen dat wat ik de "hook" noem (het element waar het resultaat van de functie aangehangen wordt) als extra argument in de functie binnenkomt, zodat je binnen de functie al een parent node hebt waaraan dingen gehangen kunnen worden.
Daar moet ik nog een oplossing voor gaan bedenken. Ben nog een XSL-n00b. Het hele plaatje zoals ik graag (zou willen) zie(n) is nog niet helemaal compleet. Kom ik vast nog op terug :)
[...]
zijn 8)
Dat dacht ik al. Maar "zijn/haar" slaat op de andere users van dit forum :)

[ Voor 5% gewijzigd door X-Lars op 24-05-2005 11:13 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Ik ga binnenkort ook nog eens kijken naar PHP MyObjects. Da's ook een object persistance layer maar dan zonder DAL (mysql/i only). Het voordeel van Propel is wel dat er ook een PHP4 runtime voor is...

[ Voor 4% gewijzigd door Genoil op 24-05-2005 11:22 ]


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Genoil, mag ik die getHook-method eens zien? :)

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public function getHook($xpath_expression, $force_list = false) {
        if(!$this->xp) $this->initXPath();
        
        $dom_node_list = $this->xp->query($xpath_expression);
        if($dom_node_list->length > 1) {
            return $dom_node_list;
        }
        if($dom_node_list->length == 1) {
            return  $force_list ? $dom_node_list : $dom_node_list->item(0);
        }
        else {
            throw new Exception("Template hook:\"".$xpath_expression."\" not found.");
        }   
    }


ik heb meerder versies rondzwerven maar dit is wel een aardige. $this->xp is gewoon een DomXpath object.

[ Voor 18% gewijzigd door Genoil op 25-05-2005 08:42 ]


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Bedankt, ik had nog niet eens de DOMXPath->query() geprobeerd.

Het voorbeeld op php.net werkt hier wel, maar onderstaande sample niet. Ik vraag me echt af waarom dit simpele testje niet werkt?

sample.xml:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>Sample</title>
    </head>
    <body>
        <h1>Here's a title</h1>
        <p>Paragraph 1.</p>
        <p>Paragraph 2.</p>
        <p>Paragraph 3.</p>
    </body>
</html>

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$doc = new DOMDocument;
$doc->load('sample.xml');

$xpath = new DOMXPath($doc);

$query = "//p";

$entries = $xpath->query($query);

foreach ($entries as $entry) {
   echo $entry->nodeValue."<br/>";
}


Edit: mjin scherm blijft leeg als ik dit uitvoer.

[ Voor 36% gewijzigd door X-Lars op 25-05-2005 11:05 ]


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

X-Lars schreef op dinsdag 24 mei 2005 @ 11:12:
code:
1
2
3
4
5
<input name="surname" id="surname">
    <xsl:attribute name="value">
        <xsl:value-of select="/webprocrm/data/customer/surname"/>
    </xsl:attribute>
</input>
Dit kan overigens nog wel een stukje korter:
code:
1
<input name="surname" id="surname" value="{/webprocrm/data/customer/surname}" />


Ik gebruik wel altijd een generieke XML-laag, maar dat is vooral omdat ik het conceptueel netter vind. Plus dat ik daarmee een aantal kleine ifs (zoals bijvoorbeeld "0 pages", "1 page", "2 pages", dat soort werk) pas in de XSLT kan afhandelen, zodat die niet mijn PHP code vervuilen met UI-specifieke shit.

Rustacean


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Manuzhai, hoe handel jij fouten af? Ik bedoel, je formulier wordt verstuurd en als deze niet aan je validatie voldoet, komt dezelfde page weer naar voren. Hoe komen deze fouten dan tot uitdrukking in je (X)HTML? Persoonlijk wil ik graag bijv. een class="error" toevoegen aan het betreffende <input>-veld. Maar met XSL pipelining lukt mij dat niet.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
X-Lars schreef op woensdag 25 mei 2005 @ 11:03:
Bedankt, ik had nog niet eens de DOMXPath->query() geprobeerd.

Het voorbeeld op php.net werkt hier wel, maar onderstaande sample niet. Ik vraag me echt af waarom dit simpele testje niet werkt?
PHP:
1
2
$xpath = new DOMXPath($doc);
$xpath->registerNamespace ("html", "http://www.w3.org/1999/xhtml");


icm

code:
1
<html xmlns:html="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

(let op het verschil xmlns:html)

wat je ook kunt doen is het xmlns attrib weghalen en dan hoef je de namespace niet meer te registeren. wat ook nog kan is wel de namespace registeren maar het xmlns attrib laten zoals je het had, maar dan moet je in je xpath queries wel de correcte namespace steeds gebruiken //html:p...
Pagina: 1