9

次の PHP コードがありますが、機能していません。エラーは表示されませんが、盲目なだけかもしれません。これを PHP 5.3.1 で実行しています。

<?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>test@example.com</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」に続いて「test@example.com」を出力するはずですが、電子メール部分は表示されません。何が問題なのですか?

-ジェフリー・リー

4

1 に答える 1

8

問題は、提供された XSLT コードにデフォルトの名前空間があることです。

したがって<firstname>、、<lastname>および<email>要素は xhtml 名前空間にあります。ただしemail、次の場合はプレフィックスなしで参照されます。

exsl:node-set($person)/email

XPath では、プレフィックスのない名前はすべて「名前空間なし」にあると見なされます。「名前空間なし」にあるexsl:node-set($person)呼び出されたの子を見つけようとしますが、子が xhtml 名前空間にあるため、これは失敗します。したがって、ノードは選択されず、出力されません。emailemailemail

解決策:

この変換:

<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>test@example.com</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>
test@example.com
</html>

注意してください:

  1. プレフィックス付きの追加された名前空間定義x

  2. の変更されたselect属性<xsl:value-of>:

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

于 2010-06-01T13:06:54.503 に答える