2010-06-01 7 views
9

Ho il seguente codice PHP, ma non funziona. Non vedo errori, ma forse sono solo cieco. Sto eseguendo questo su PHP 5.3.1.Ottenere exsl: node-set per funzionare in PHP

<?php 
$xsl_string = <<<HEREDOC 
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns="http://www.w3.org/1999/xhtml" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:exsl="http://exslt.org/common" 
       extension-element-prefixes="exsl"> 
    <xsl:template match="/"> 
    <p>Hello world</p> 
    <xsl:variable name="person"> 
     <firstname>Foo</firstname> 
     <lastname>Bar</lastname> 
     <email>[email protected]</email> 
    </xsl:variable> 
    <xsl:value-of select="exsl:node-set(\$person)/email"/> 
    </xsl:template> 
</xsl:stylesheet> 
HEREDOC; 

$xml_dom = new DOMDocument("1.0", "utf-8"); 
$xml_dom->appendChild($xml_dom->createElement("dummy")); 

$xsl_dom = new DOMDocument(); 
$xsl_dom->loadXML($xsl_string); 

$xsl_processor = new XSLTProcessor(); 
$xsl_processor->importStyleSheet($xsl_dom); 
echo $xsl_processor->transformToXML($xml_dom); 
?> 

Questo codice dovrebbe uscita "Ciao mondo" seguito da "[email protected]", ma non sembra la parte e-mail. Qualche idea di cosa c'è che non va?

-Geoffrey Lee

+0

buona domanda (+1). Vedi la mia risposta per una spiegazione e una soluzione completa. –

risposta

8

Il problema è che il codice XSLT fornito ha un namespace di default.

Pertanto, gli elementi <firstname>, <lastname> e <email> sono nello spazio nomi xhtml. Ma email viene fatto riferimento, senza alcun prefisso:

exsl:node-set($person)/email 

XPath considera tutti i nomi senza prefisso di essere in "no namespace". Prova a trovare un figlio di exsl:node-set($person) chiamato email che si trova in "nessun spazio dei nomi" e questo non ha successo, perché il suo figlio email si trova nello spazio dei nomi xhtml. Quindi nessun nodo email è selezionato ed emesso.

Soluzione:

Questa trasformazione:

<xsl:stylesheet version="1.0" 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:x="http://www.w3.org/1999/xhtml" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    exclude-result-prefixes="exsl x"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <html> 
    <p>Hello world</p> 
    <xsl:variable name="person"> 
     <firstname>Foo</firstname> 
     <lastname>Bar</lastname> 
     <email>[email protected]</email> 
    </xsl:variable> 
    <xsl:text>&#xA;</xsl:text> 
    <xsl:value-of select="exsl:node-set($person)/x:email"/> 
    <xsl:text>&#xA;</xsl:text> 
    </html> 
    </xsl:template> 
</xsl:stylesheet> 

quando applicato su qualsiasi documento XML (non utilizzato), produce il risultato voluto:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:x="http://www.w3.org/1999/xhtml"> 
    <p>Hello world</p> 
[email protected] 
</html> 

Do atto:

  1. La definizione dello spazio dei nomi aggiunto con prefisso x

  2. L'cambiato select attributo della <xsl:value-of>:

exsl:node-set($person)/x:email

+0

Ah, questo ha perfettamente senso ora. Grazie per la tua risposta ben scritta! – geofflee

Problemi correlati