使用PHP添加,更新和编辑XML文件

时间:2008-12-18 11:59:25

标签: php xml simplexml

我有一个xml文件,我想创建一个表单/表来使用PHP添加,编辑和删除记录。目前我使用simpleXML加载XML文件,并在各种页面上显示其内容。

有没有办法可以创建一个显示所有结果的表,并允许我编辑或删除表中特定行,表示XML文件中的完整记录。

点击编辑时,我希望记录中的详细信息以用户可以更改的格式显示,然后保存,更新XML文件和相应的网页。

我需要在PHP中完成这项工作,最好使用SimpleXML,尽管可以通过其他方式建议使用PHP。

干杯

3 个答案:

答案 0 :(得分:3)

XSLT是您将XML数据库文件转换为您希望在网页上显示的格式的朋友。您创建一个XSL模板,其中包含每个记录所需的所有HTML,然后使用for-each语句遍历XML文件。我将给出一个粗略的概述,如果需要可以提供更多细节。

这是我用来通过AJAX执行XSLT(使用XSL文件处理XML文件)的通用PHP文件。这个设置用于在浏览器的GET调用中传递所需的(和可选的,如果需要的话)输入。 p#n和p#v(请参阅下面代码顶部的注释)是在要使用某些输入参数影响输出的情况下要传递到XSL文档的参数和值对。在这种情况下,输出将回显给浏览器。以下是运行XML数据库的PHP和XSLT转换,以便为您的Web显示创建HTML(表格或您在XSL文件模板中放置的任何内容):

<?php
//REQUIRED INPUTS:
// - xml: path to xml document
// - xsl: path to xsl style sheet
// - pCount: number of parameters to be passed to xslt (send zero '0' if none)
//OPTIONAL INPUTS (must have as many as specified in pCount, increment '1' in
//names below up a number for each iteration):
// - p1n: name of first parameter
// - p1v: value of first parameter

//SET Paths 
$xmlPath = $_GET['xml'];
$xslPath = $_GET['xsl'];

// Load the XML source
$xml = new DOMDocument;
$xml->load($xmlPath);

$xsl = new DOMDocument;
$xsl->load($xslPath);

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

//Set Parameter(s), if present
$xslParamCount = $_GET['pCount']; //Check number of xsl parameters specified in GET
for ($i=1; $i<=$xslParamCount; $i++){
   $xslParamName = $_GET['p'.$i.'n'];
   $xslParamValue = $_GET['p'.$i.'v'];
   $proc->setParameter( '', $xslParamName, $xslParamValue);    //Set parameters for XSLTProcessor
}

// TRANSFORM
echo $proc->transformToXML($xml);

// SET Mime Type
$mime = "application/xhtml+xml";
$charset = "iso-8859-1";
header("Content-Type: $mime;charset=$charset");
?> 

下面是一个XSL文件模板示例,它采用XML数据库文档并将其转换为HTML以便在网页中插入。请注意HTML span标记。所有xsl标记都是处理指令,用于确定模板中HTML标记内部和周围的内容。在这种情况下,我们过滤结果并根据传入XSL文件的输入参数选择要显示的相应数据(参见附近顶部的xsl:param项目):

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
 <xsl:param name='testId'/>
 <!--Input options for following param: localUse, notLocalUse, nottestId, or '' (all)-->
 <xsl:param name='matchType'/>
 <xsl:template match='/'>
   <xsl:choose>
      <xsl:when test="$matchType='localUse'">
         <xsl:for-each select="//test[@id=$testId and @localUse='yes']">
            <xsl:sort select="../@id"/>
            <div><xsl:if test='../@localPrefTestId=$testId'><xsl:attribute name='class'>preferredTest</xsl:attribute></xsl:if>
               <span class='productStockCode'>
                  <xsl:if test='../@localPrefTestId=$testId'>
                     <xsl:attribute name='title'>Preferred test for this product</xsl:attribute>
                  </xsl:if>
                  <xsl:if test='../@localPrefTestId!=$testId'>
                     <xsl:attribute name='title'>Alternate (not preferred) test for this product - see note to right</xsl:attribute>
                  </xsl:if>
                  <xsl:value-of select='../@id'/>
               </span>
               <span class='productStockName'>
                  <xsl:if test='../@localPrefTestId=$testId'>
                     <xsl:attribute name='title'>Preferred test for this product</xsl:attribute>
                  </xsl:if>
                  <xsl:if test='../@localPrefTestId!=$testId'>
                     <xsl:attribute name='title'>Alternate (not preferred) test for this product - see note to right</xsl:attribute>
                  </xsl:if>
                  <xsl:value-of select='../@name'/>
               </span>
               <span class='producttestNote'>
                  <xsl:value-of select='child::localPrefNote'/>
               </span>
               <span class='productDeleteButton'>
                  <input onClick='remProdLink(this)' title='Click to remove link to this product' type='image' src='button_tiny_X_grey.bmp'></input>
               </span>
            </div>
         </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
         <p>Server Error: GET must specify matchType parameter value of 'localUse', 'notLocalUse', 'nottestId', or '' (for all)</p>
         <p>matchType received: <xsl:value-of select='$matchType'/></p>
      </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
 <!--Note the output method="html" below is required for this to insert correctly into a web page; without this it may nest improperly if any divs are empty-->
 <xsl:output method="html" omit-xml-declaration="yes"/>
</xsl:stylesheet>

请注意,所有xsl测试都是XPath表达式。

要删除行,您可以在该行上使用“this”参数调用JavaScript函数(请参阅上面代码中的onClick ='remProdLink(this)')以引用该行,然后获取唯一行JavaScript中行的标识符,如下所示:

function remProdLink(obj){
   //get unique id via Dom from passed in object reference
   //edit everything after "obj" below to get to the unique id in the record
   var testCode = obj.parentNode.parentNode.firstChild.nextSibling.innerHTML;
   //code to send AJAX POST to server with required information goes here
}

在服务器端,您的PHP接收带有唯一标识符的AJAX POST,将XML数据库文件加载到simpleXml中,通过XPath查找节点,并将其删除,如下所示:

<?php
   //Move url encoded post data into variables
   $testCode = $_POST['testCode']; //$testCode should be a unique id for the record

   //load xml file to edit
   $xml = simplexml_load_file('yourDatabase.xml');

   //find target node for removal with XPath
   $targets = $xml->xpath("//testCode[@id=$testCode]");

   //import simpleXml reference into Dom to do removal
   $dom2 = dom_import_simplexml($targets[0]);
   $dom2->parentNode->removeChild($dom2);

   //format xml to save indented tree (rather than one line) and save
   $dom = new DOMDocument('1.0');
   $dom->preserveWhiteSpace = false;
   $dom->formatOutput = true;
   $dom->loadXML($xml->asXML());
   $dom->save('yourDatabase.xml');
?>

对于编辑项目,您可以使用另一个与删除项目类似的JavaScript函数,如上所述,使用保存更改按钮在网页上的该项目下创建一个表单,并在按下该按钮时调用另一个JavaScript函数到AJAX POST到服务器,再次类似于删除。只有这次你的POST需要包含记录中可能已编辑的所有信息以及记录的唯一ID。 PHP文件将找到相应的记录(与删除相同),然后您可以在PHP中编辑该记录的部分,或者只删除它并创建并附加新版本的记录。

我不确定你需要多少细节。希望这会给你一个良好的开端。如果您需要有关其任何部分的更多详细信息,请评论我的答案。祝你好运!

答案 1 :(得分:1)

我建议您使用DomDocument和DomXPath,而不是SimpleXml。但是,一般来说,XML不是存储数据的最佳媒介 - 您应该使用数据库来处理您正在做的任何事情。如果您需要轻松交换数据,您可以使用SQLite,而不是更常见的MySql。

答案 2 :(得分:0)

您可以使用本机XML数据库来帮助创建,添加,更新和检索xml文档和节点。我过去使用BerkeleyDBXML(现在是Oracle的一部分)并取得了成功。还有一个PHP库。