[XSL/XML] Alle XML data uit een XML-bestand wordt getoond.

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
Ik heb een XML-bestand waarin data mbt een aantal productgroepen staat, zoals DVD's en games. Op dit XML-bestand pas ik XSL-templates toe door aan de server-side met behulp van PHP de standaard PHP XSL-processor toe te passen. Zie code:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

   $xslDoc = new DOMDocument();
   $xslDoc->load("XSLbestand.xsl");

   $xmlDoc = new DOMDocument();
   $xmlDoc->load("XMLbestand.xml");

   $proc = new XSLTProcessor();
   $proc->importStylesheet($xslDoc);
   echo $proc->transformToXML($xmlDoc);

?>


Nu werkt dit allemaal goed op 1 ding na. Alle data uit het XML bestand wordt nu getoond op het scherm.
Ik wil juist alleen bepaalde data op het scherm tonen welke zich tussen bepaalde XML-tags bevindt.
De bedoeling is bijvoorbeeld dat op een bepaalde pagina op de website alleen data mbt de DVD's wordt getoond, dus alleen producten welke tussen de <DVD> en </DVD> tags staan. Wat er nu gebeurt is dat alle data uit het XML bestand wordt getoond, ook alles dat tussen <GAMES> tags staat en dat is juist niet de bedoeling.

Ik weet dus alleen niet hoe ik dat moet doen met XSL (of PHP). (De XSL styling moet dus wel blijven werken op de gekozen data uit het XML-bestand.)

Iemand kwam met de volgende suggestie: "Onderdruk de XML elementen die je niet ge-output wil zien met een nieuwe lege XSL template".
code:
1
<xsl:template match="specifiekElement"></xsl:template>


Het bovenstaande lijkt me alleen handig in zeer specifieke gevallen, maar niet in mijn geval, want op de ene pagina wil ik een bepaald element wel tonen en op een andere pagina niet. Als ik een element permanent zou onderdrukken op de bovenstaande manier, dan heb ik die flexibiliteit namelijk niet om het XML element te tonen wanneer ik wil.

Een PHP oplossing zoals het volgende zou het ook kunnen laten werken, alleen is het volgende stukje code mijn eigen verzinsel en werkt het niet:
PHP:
1
2
3
4
5
//Echo alleen alles tussen de DVD-tags
echo $proc->transformToXML($xmlDoc->root[0]->dvd); 

//Het bovenstaande stukje code geeft de volgende error:
//Warning: XSLTProcessor::transformToXml() expects parameter 1 to be object, null given


Een andere oplossing is een X-Path expressie loslaten op het geladen XML bestand, echter de x-path functie werkt alleen op een SimpleXML object vermoed ik.

[ Voor 39% gewijzigd door Arcane Apex op 07-03-2009 11:12 ]


Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
De reden dat het gehele XML bestand wordt ge-output door de XSLT processor is waarschijnlijk omdat $xmlDoc->load() het gehele XMLbestand.xml als parameter meekrijgt. Misschien is er een manier om een beperkt gedeelte van het XML-bestand als parameter mee te geven. Ik weet alleen niet hoe ik dat zou moeten doen.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Je bent XML aan het gebruiken voor iets waar het niet voor bedoeld is.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
En dit staat in WEB omdat... :?
Waar hoort mijn topic?

WEB >> PRG

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
Omdat ik niet weet of de oplossing XSL-gebaseerd is of PHP-gebaseerd is of beide.

Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
Ik denk dat ik er qua oplossing bijna ben. Ik krijg echter alleen nog 1 foutmelding.

Foutmelding: Warning: DOMDocument::importNode() expects parameter 1 to be DOMNode

De reden voor de foutmelding vermoed ik is dat de methode importNode alleen een DomNode als parameter accepteert, terwijl ik het juist een DOMNodeList als parameter meegeef. De reden daarvoor is dat de xpath->query() methode alleen een DOMNodeList als output geeft. De reden waarom ik het toch op deze manier probeerde is omdat ik geen methode kon vinden in de DOMDocument klasse welke een DOMNodeList kon importeren.


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
        $xslDoc = new DOMDocument();
        $xslDoc->load("XSLbestand.xsl");        
        
        $xmlDoc = new DOMDocument();
        $xmlDoc->load("XMLbestand.xml");        
        
        $xpath = new DOMXpath($xmlDoc);     
        $extractedElements = $xpath->query("/root/dvd");        
        
        $xmlDocStripped = new DOMDocument();
        $xmlDocStripped->importNode($extractedElements);                
        
        $proc = new XSLTProcessor();
        $proc->importStylesheet($xslDoc);
        
        echo $proc->transformToXML($xmlDocStripped);
?>

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het idee van XSLT is juist dat je kan transformeren, en dus ook elementen weg kunt laten.

Je kunt toch gewoon met een for-each door de gewenste elementen heen lopen, en de rest niet processen?

XSLT:
1
2
3
<xsl:for-each select="/root/dvd">
    <!-- Hier je template -->
</xsl:for-each>

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • eek
  • Registratie: Februari 2001
  • Laatst online: 06-04-2020

eek

@MagickNET

PHP:
1
 $xmlDocStripped->importNode($extractedElements[0]);


Of heb je meerdere dvd nodes?

en bovenstaande is natuurlijk slimmer

[ Voor 15% gewijzigd door eek op 09-03-2009 10:27 ]

Skill is when luck becomes a habit.


Acties:
  • 0 Henk 'm!

  • Pkunk
  • Registratie: December 2003
  • Laatst online: 11-09 17:52
Waarom ga je een XPath in je php uitvoeren? Daar is xslt nou juist zo lekker voor. Gebruik je voor elk xml bestand dezelfde xsl ofzo? Of andersom..

Over die foutmelding.. Je krijgt een NodeList terug. Dat ziet er dus ongeveer zo uit:
XML:
1
2
3
<dvd title='bla'/>
<dvd title='bla'/>
<dvd title='bla'/>

Vervolgens probeer je een nieuw XMLDocument te maken met die nodeList. Een xml document moet echter altijd een root node hebben. Je zal er dus zoiets van moeten maken:
XML:
1
2
3
4
5
<dvds>
  <dvd title='bla'/>
  <dvd title='bla'/>
  <dvd title='bla'/>
</dvds>

Wat je dus moet doen is eerst een rootnode maken in xmlDocStripped. En vervolgens dat lijstje aan die rootnode appenden.

Maargoed, zoals ik al eerder zei vermoed ik dat je beter iets kan veranderen aan je opzet als je dit soort fratsen in php gaat doen.

Hallo met Tim


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
CodeCaster schreef op zondag 08 maart 2009 @ 20:53:
Je bent XML aan het gebruiken voor iets waar het niet voor bedoeld is.
Leg eens uit, wat is er dan niet zo bedoeld? En hoe zou het dan wel moeten?

Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
Het is gelukt, ik heb een oplossing gevonden. Bij mijn bovenstaande poging bleek ik veel te moeilijk te doen. De oplossing was het doorgeven van een parameter mbv PHP naar het XSL bestand.


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$xslDoc = new DOMDocument();
$xslDoc->load("XSLbestand.xsl");        
        
$xmlDoc = new DOMDocument();
$xmlDoc->load("XMLbestand.xml");                
        
$proc = new XSLTProcessor();
$proc->importStylesheet($xslDoc);       
        
//Hier pass ik een GET variabele uit de url naar het XSL bestand
$proc->setParameter(null, 'product', $_GET['product']);     
                
echo $proc->transformToXML($xmlDoc);
?>


Ook in het XSL bestand definieer ik een "product" parameter. Afhankelijk van de waarde van de parameter kies ik doormiddel van choose en when statements met xpath de juiste range aan elementen en pas op die range de templates toe.

(De formatting is wat messed up, maar het punt is duidelijk denk ik)
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
<xsl:param name="product" />


<xsl:template match="/">
     <xsl:choose>
          <xsl:when test="$product = 'dvd'">
        <xsl:for-each select="/root/dvd">
            <xsl:apply-templates/> 
        </xsl:for-each>
      </xsl:when>
      <xsl:when test="$product = 'games'">
        <xsl:for-each select="/root/games">
            <xsl:apply-templates/>
        </xsl:for-each>
      </xsl:when>           
     </xsl:choose>      
</xsl:template>

<xsl:template match="/dvdElement">
     <!-- Hier worden de dvd elementen gestyled -->
</xsl:template>

<xsl:template match="/gamesElement">
     <!-- Hier worden de games elementen gestyled -->
</xsl:template>

Acties:
  • 0 Henk 'm!

  • oer
  • Registratie: Oktober 2006
  • Laatst online: 21-09 14:30

oer

je kunt overigens ook gewoon <xsl:apply-templates select="/root/dvd/*"/> doen in plaats van die <xsl:for-each/> loop.

Acties:
  • 0 Henk 'm!

  • Pkunk
  • Registratie: December 2003
  • Laatst online: 11-09 17:52
kleine tip: je heft niet perse met for-each door alle elementen te itereren. Je kan er ook meteen een apply-templates op los laten.
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<xsl:param name="product" />

<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="$product = 'dvd'">
      <xsl:apply-templates select="/root/dvd/dvdElement"/>
    </xsl:when>
    <xsl:when test="$cproduct = 'games'">
      <xsl:apply-templates select="/root/games/gamesElement"/>
    </xsl:when>         
  </xsl:choose>     
</xsl:template>

<xsl:template match="dvdElement">
     <!-- Hier worden de dvd elementen gestyled -->
</xsl:template>

<xsl:template match="gamesElement">
     <!-- Hier worden de games elementen gestyled -->
</xsl:template>

Daarnaast snap ik niet waarom je in je choose 2 verschillende variabelen gebruikt. Typo? Als je dezelfde variabele gebruikt zou je zoiets kunnen doen (er vanuitgaand dat er in je get "product" of "games" staat):
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<xsl:param name="product" />

<xsl:template match="/"> 
  <xsl:apply-templates select="root/*[name()=$product]/*"/>   
</xsl:template>

<xsl:template match="dvdElement">
     <!-- Hier worden de dvd elementen gestyled -->
</xsl:template>

<xsl:template match="gamesElement">
     <!-- Hier worden de games elementen gestyled -->
</xsl:template>

Hallo met Tim


Acties:
  • 0 Henk 'm!

  • Arcane Apex
  • Registratie: Juni 2003
  • Laatst online: 30-01 15:19
Timlog schreef op maandag 09 maart 2009 @ 21:09:
Daarnaast snap ik niet waarom je in je choose 2 verschillende variabelen gebruikt. Typo?
Dat was idd een typo. (Fixed)

Bedankt voor de tips Oer en Timlog.

[ Voor 22% gewijzigd door Arcane Apex op 09-03-2009 21:15 ]

Pagina: 1