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


How can I insert xml data (as variable) from PHP using 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变量。

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

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

阅读XSLT处理器文档,了解使用什么API将外部参数传递到转换

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

本质上: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方法导出[参见PHP手册])为:

/**
 * @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;标记。

我仍然想知道你想要从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);
}
?>