[XSLT/PHP] probleem met document() en scope

Pagina: 1
Acties:

Onderwerpen


  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Eerst even wat achtergrond-informatie. Ik ben voor een CMS de laatste tijd veel bezig met XSLT en XML. Een van de onderdelen van het CMS is dat items (pagina's) niet alleen (X)HTML kunnen bevatten, maar ook bijvoorbeeld XML als deze:

XML:
1
2
3
4
5
<product>
    <naam>Testproduct</naam>
    <prijs>100</prijs>
    <omschrijving>Dit is een testproduct</omschrijving>
</product>


Omdat alles (ook de pagina-inhoud) bij het bekijken door de XSLT-molen wordt gehaald, kun je dit heel eenvoudig omzetten naar een mooi HTML-ding. (De grap hiervan is dat je in 1x in je templates van alle 'producten' in het CMS de layout kan veranderen, in een 'traditioneel' CMS moet je daarvoor alle pagina's die een 'product' bevatten aanpassen).

Helaas zijn niet alle mensen even handig met XML, en daarom had ik bedacht een soort editor te maken in de backend van het CMS. Hier kan een beheerder dan gewoon fijn de details van het product invullen en het CMS genereert dan fijn de XML-code die je anders zelf had moeten maken. Een voorbeeld van zo'n formulier vindt je hier.

Om dat formulier te maken heb ik in dit bestand vastgelegd welke velden er zijn voor een 'product'. In mijn template genereer ik het formulier ongeveer zo:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<xsl:template match="/">
.. hier wat pagina zut..
<xsl:apply-templates match="document('objects.xml')/web-objects/object[@name=$type]"/>
</xsl:template>

<xsl:template match="object">
...hier door de properties van het object loopen...
<xsl:apply-templates select="property"/>
</xsl:template>

<xsl:template match="property">
...input veld maken enzo...
<input>
<xsl:attribute name="value">
<xsl:value-of select="/template/values[@field='naamvanveld']"/>
</xsl:attribute name="value">
</input>
</xsl:template>


Het probleem is nu dat die <xsl:value-of select="/template/default"/> hierboven niet werkt. Alle value-of's hebben in dat xsl:template blok namelijk toepassing op de door document() geopende XML. Maar ik wil toch gewoon bij de variabelen uit het 'originele' XML-document (daar zitten wat parameters in) kunnen. Is hier een nette oplossing voor? Wat normaal zou kunnen is een xsl:variable maken, maar dat gaat in dit geval niet, omdat ik de formuliervelden wil vullen met standaard-waardes die uit de database komen, en dat zijn er nogal wat....

Ik hoop dat het zo een beetje duidelijk is :)

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Ik denk dat ik het verhaal wat moet versimpelen: stel ik heb het volgende XML bronbestand:

XML:
1
2
3
4
5
6
7
<?xml version='1.0' ?>

<template>
    <default-values>
        <field name="naam">Jan</field>
   </default-values>
</template>


En een ander .xml bestand, objects.xml:

XML:
1
2
3
4
5
<web-objects>
    <object name="persoon">
        <property name="naam"/>
    </object>
</web-objects>


Daarbij heb ik de volgende .xsl die met de eerste xml wordt aangeroepen:

XML:
1
2
3
4
5
6
7
8
<xsl:template match="/">
    <xsl:for-each select="document('objects.xml')/web-objects/object[@name='persoon']/property">
        Hier kan ik dan fijn <xsl:value-of select="@name"/> 
doen voor de propertynaam. 
Maar hoe kan ik vanaf hier bij de data uit het
 eerste XML-bestand komen?
    </xsl:for-each>
</xsl:template>


Hopen dat dat wat meer reacties oproept :)

[ Voor 16% gewijzigd door MisterData op 11-09-2004 18:29 ]


Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Dit zou de oplossing moeten zijn (ik ben zelf nog maar even gaan zoeken, blijkbaar is het geen 'makkelijk' probleem gezien het enorme aantal reacties op deze thread):
It's not. XPath says that "A / by itself selects the root node of the
document ***containing the context node.***"

The solution is to have a top-level variable pointing to the root of the
main document:

<xsl:stylesheet>

<xsl:variable name="main" select="/"/>

and then use

sum($main//amount)

James