【问题标题】:Getting exsl:node-set to work in PHP让 exsl:node-set 在 PHP 中工作
【发布时间】:2011-02-26 08:22:51
【问题描述】:

我有以下 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”,但不显示电子邮件部分。知道有什么问题吗?

-杰弗里·李

【问题讨论】:

  • 好问题 (+1)。请参阅我的答案以获得解释和完整的解决方案。

标签: php xml xslt exslt


【解决方案1】:

问题在于提供的 XSLT 代码有一个默认命名空间。

因此,&lt;firstname&gt;&lt;lastname&gt;&lt;email&gt; 元素位于 xhtml 命名空间中。但是email 的引用没有任何前缀:

exsl:node-set($person)/email

XPath 认为所有无前缀的名称都在“无命名空间”中。它试图找到一个名为 emailexsl:node-set($person) 的子代,该子代位于“无命名空间”中,但这是不成功的,因为它的 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>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. &lt;xsl:value-of&gt;select属性改变:

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

【讨论】:

  • 啊,现在说得通了。感谢您精心编写的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多