如何使用XSLT从PHP插入xml数据(作为变量)

时间:2012-07-17 12:39:40

标签: php xml xslt

我需要通过集成一些XML文件来生成主XML文件。如果我们在磁盘上的某些位置存储了不同的子XML文件,则可以实现这一点。但在我的例子中,子XML文件是动态XML数据。它们不会存储在任何地方,而是动态生成。那么如何插入这些子XML数据来生成主XML文件。

我的意见是:

<root>
  <element id="1">
  </element>
  <element id="2">
  </element>
</root>

我的输出是:

<root>
   <element id="1">
      <section>
         <record>12</record>
      </section>
   </element>
   <element id="2">
      <section>
          <input>menu</input>
      </section>
   </element>
</root>

在上面的输出中,XML数据(<section><record>12</record></section>)应来自PHP变量。

3 个答案:

答案 0 :(得分:0)

您必须将两个“动态”XML文档作为参数传递给转换

每个“动态文档”都应该已经解析为XML文档(在其他XSLT处理器API中有一个方法 - 例如XmlDocument.LoadXml() - 它接受一个字符串并将其解析为XML并创建一个(解析的)XML文档。)

阅读您的XSLT处理器文档,了解用于将外部参数传递给转换的API(

答案 1 :(得分:0)

这是一个老话题,但没有给出令人满意的答案;最近我遇到了类似的情况,我相信解决方案足够普遍适用于像这样的问题。

基本上:PHP和XSLT处理器通过DOMNode对象(参数和返回值)进行通信。因此,可以使用PHP构造一个DOMNode对象,并根据XSLT处理器的请求返回它。

鉴于上面的例子,我们将有以下XSLT:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:php="http://php.net/xsl">
  <xsl:template match="/root">
    <root>
      <xsl:apply-templates select="element" />
    </root>
  </xsl:template>

  <xsl:template match="element">
    <element>
      <!-- Pass the selected id attributes to a PHP callback,
           then literally include the XML as returned from PHP.
           Alternatively, one could use xsl:apply-templates
           to further transform the result. -->
      <xsl:copy-of select="php:function('xslt_callback', @id)" />
    </element>
  </xsl:template>
</xsl:stylesheet>

PHP函数(此函数应使用registerPHPFunctions方法[see php manual]导出)将是:

/**
 * @param  DOMAttr[]  $attr_set An array of DOMAttr objects,
 *                              passed by the XSLT processor.
 * @return DOMElement           The XML to be inserted.
 */
function xslt_callback ($attr_set) {
  $id = $attr_set[0]->value;
  return new DOMElement('section', $id); //whatever operation you fancy
}

导致以下XML:

<root>
  <element>
    <section>1</section>
  </element>
  <element>
    <section>2</section>
  </element>
</root>

php函数xslt_callback可以使用所选的id执行任何操作。我们假设在此示例中$attr_set始终只包含一个选定的属性。根据具体情况,可能需要进行一些范围或类型检查;但是,这只会使示例骨架不必要地复杂化。

注意:只需从PHP返回XML字符串,就会为每个&lt;&gt;插入<>个标记。

答案 2 :(得分:0)

我仍然想知道您想从php获得什么 我假设您可以重新打印并在循环中抛出类似以下内容的内容,但我很乐意进一步探讨如何通过动态xml生成来制作一些网站前端。在此页面中更改通过切换值来执行的scalors选项是什么,在php中是不同的,有很多事情可以做,请进一步告诉我您想要什么

<?php
$i=1;
$option = "default";
$elemental = 1;
$StrRecord = "12";
$StrInput = "menu";
$domdoc = new DOMDocument();
$domdoc->preserveWhiteSpaces = false;
$domdoc->load(realpath('xmlfile.xml'));
$root = new DOMElement('root');
$element = new DOMElement('element');
$section = new DOMElement('section');
$record = new DOMElement('record', $StrRecord);
$elementi = new DOMElement('element');
$sectioni = new DOMElement('section');
$inputi = new DOMElement('input', $StrInput);
$elementid= new DOMAttr('id', $elemental+1);
$elementidi= new DOMAttr('id', $elemental+1);

$domdoc->appendChild($root);
$root->appendChild($element);
$element->appendChild($section);
$section->appendChild($record);
$root->appendChild($elementi);
$elementi->appendChild($sectioni);
$sectioni->appendChild($inputi);
$sectioni->appendChild($inputi);
$element->appendChild($elementid);
$elementi->appendChild($elementidi);
$domdoc->formatOutput = true;
$domdoc->save('xmlfile.xml');

$xmldoc= new DOMDocument();
$xmldoc->load(realpath('xmlfile.xml'));
$xpath = new DOMXpath($xmldoc);

switch($option){
case "record":
$query = ('/root/element/section/record');
break;
case "input":
$query = ('/root/element/section/input');
break;
case "default":
$query = ('/root/element[@id="'. $i.'"]/');
break;
}
$nodeList = $xpath->query($query);
foreach($nodeList as $node){
echo($node->nodeValue);
}
?>