2010-06-01 26 views
9

我有以下PHP代碼,但它不起作用。我沒有看到任何錯誤,但也許我只是失明。我在PHP 5.3.1上運行這個。獲取exsl:node-set在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); 
?> 

此代碼應該輸出「Hello world」後跟「[email protected]」,但電子郵件部分不會顯示。任何想法有什麼不對?

-Geoffrey李

+0

很好的問題(+1)。請參閱我的答案以獲得解釋和完整解決方案。 – 2010-06-01 13:07:42

回答

8

的問題是,所提供的XSLT代碼有一個默認的命名空間。

因此,<firstname>,<lastname><email>元素位於xhtml命名空間中。但email是沒有任何前綴的引用:

exsl:node-set($person)/email 

的XPath考慮所有前綴的名字是在「沒有命名空間」。它試圖找到名爲emailexsl:node-set($person)的孩子,該孩子處於「no namespace」,並且這是不成功的,因爲其email孩子位於xhtml命名空間中。因此沒有選擇並輸出email節點。

解決方案

這種轉變:

<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> 

當任何XML文檔(未使用)應用時產生通緝的結果

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

待辦事項

  1. 前綴x

  2. <xsl:value-of>的改變select屬性添加的命名空間定義:

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

+0

啊,現在完全有意義。謝謝你的答案! – geofflee 2010-06-01 13:44:53