使用 PHP 添加、更新和编辑 XML 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/377632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add, update and edit an XML file with PHP
提问by user47378
I have an xml file which I would like to create a form/table around to add, edit and delete records using PHP. Currently I use simpleXML to load the XML file, and display its content on various pages.
我有一个 xml 文件,我想围绕它创建一个表单/表格,以使用 PHP 添加、编辑和删除记录。目前我使用 simpleXML 加载 XML 文件,并在各个页面上显示其内容。
Is there any way I can create a table that shows all results, and allows me to either edit or delete that particular row of the table which represents a full record within the XML file.
有什么方法可以创建一个显示所有结果的表格,并允许我编辑或删除表格中代表 XML 文件中完整记录的特定行。
When clicking edit I would like the details from the record to appear in a form which the user can change and then save out, updating the XML file and the corresponding web page.
单击编辑时,我希望记录中的详细信息以用户可以更改的形式显示,然后保存,更新 XML 文件和相应的网页。
I need this done in PHP, preferably using SimpleXML, though open to suggestions of other ways to do this with PHP.
我需要在 PHP 中完成这项工作,最好使用 SimpleXML,尽管愿意接受使用 PHP 执行此操作的其他方法的建议。
Cheers
干杯
回答by Witman
XSLT is your friend for converting the XML database file to the format you want to display on the web-page. You create an XSL template that includes all the HTML you want for each record and then iterate through the XML file with a for-each statement. I'll give a rough overview and can help with more details if needed.
XSLT 是您将 XML 数据库文件转换为您希望在网页上显示的格式的朋友。您创建一个 XSL 模板,其中包含您想要用于每条记录的所有 HTML,然后使用 for-each 语句遍历 XML 文件。我将给出一个粗略的概述,如果需要,可以帮助提供更多细节。
Here's the generic PHP file I use to do XSLT (process an XML file with an XSL file) via AJAX. This one is setup to work with required (and optional, if desired) inputs passed in a GET call from the browser. p#n and p#v (see comments at top of code below) are parameter and value pairs to be passed into the XSL document in cases where you want to use some input parameter to affect the output. In this case output is echoed back to the browser. Here's the PHP to run the XML database through and XSLT transformation to create the HTML for your web display (table, or whatever you put in the XSL file template):
这是我用来通过 AJAX 执行 XSLT(使用 XSL 文件处理 XML 文件)的通用 PHP 文件。这个设置用于处理从浏览器通过 GET 调用传递的必需(和可选,如果需要)输入。p#n 和 p#v(请参阅下面代码顶部的注释)是要传递到 XSL 文档中的参数和值对,以防您想使用某些输入参数来影响输出。在这种情况下,输出会回显到浏览器。下面是运行 XML 数据库的 PHP 和 XSLT 转换,为您的 Web 显示(表格,或您放入 XSL 文件模板的任何内容)创建 HTML:
<?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");
?>
Below is an example of an XSL file template taking an XML database document and converting it to HTML for insertion in a web page. Note the HTML span tags. All the xsl tags are processing instructions that determines what goes in and around the HTML tags in the template. In this case, we are filtering results and choosing appropriate data to display based on input parameters passed into the XSL file (see xsl:param items at near top):
下面是一个 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>
Note that all the xsl tests are XPath expressions.
请注意,所有 xsl 测试都是 XPath 表达式。
To delete a row you can have a button on that row that calls a JavaScript function with the "this" argument (see onClick='remProdLink(this)' in code above) to reference the row, and then grab the unique identifier of the row in JavaScript something like this:
要删除一行,您可以在该行上有一个按钮,该按钮调用带有“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
}
On the server end, your PHP receives the AJAX POST with the unique identifier, loads the XML database file into simpleXml, finds the node via XPath, and removes it, something like this:
在服务器端,您的 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');
?>
As for editing an item, you can have another JavaScript function called similarly to the one for deleting as noted above, create a form under that item on the web page with a save changes button, and when that button is pressed call another JavaScript function to AJAX POST to the server, again similarly to deleting. Only this time your POST will need to include all the information that could have been edited in the record along with the record's unique ID. PHP file will find the appropriate record (same as for deleting), and then you can either edit parts of that record in PHP, or just remove it and the create and append the new version of the record.
至于编辑一个项目,您可以调用另一个类似于上述删除的 JavaScript 函数,在网页上的该项目下创建一个带有保存更改按钮的表单,当按下该按钮时,调用另一个 JavaScript 函数以AJAX POST 到服务器,同样类似于删除。只是这一次,您的 POST 需要包含所有可以在记录中编辑的信息以及记录的唯一 ID。PHP 文件将找到适当的记录(与删除相同),然后您可以在 PHP 中编辑该记录的一部分,或者只是删除它并创建并附加新版本的记录。
I'm not sure how many details you need. Hopefully this gives you a good start. Please comment on my answer if you need more details on any part of it. Good luck!
我不确定您需要多少详细信息。希望这能给你一个好的开始。如果您需要有关其中任何部分的更多详细信息,请评论我的回答。祝你好运!
回答by troelskn
I would suggest that you use DomDocument, and DomXPath, rather than SimpleXml. However, in general, XML is not an optimum medium for storage of data - You should probably use a database for whatever it is you're doing. If you need to exchange the data easily, you could perhaps use SQLite, instead of the more common MySql.
我建议您使用 DomDocument 和 DomXPath,而不是 SimpleXml。但是,一般来说,XML 不是存储数据的最佳媒介——无论您在做什么,您都应该使用数据库。如果您需要轻松交换数据,您或许可以使用 SQLite,而不是更常见的 MySql。
回答by null
You can use a native XML database to facilitate creating, adding, updating and retrieving xml documents and nodes. I've used BerkeleyDBXML(now part of Oracle) in the past with success. There's is a PHP library available as well.
您可以使用本机 XML 数据库来促进创建、添加、更新和检索 xml 文档和节点。我过去曾成功地使用过BerkeleyDBXML(现在是 Oracle 的一部分)。还有一个可用的 PHP 库。

