在页面上,我让它从 XML 文件加载内容。 然后有一个表单,根据与 $_GET['cat'] 值匹配的类别名称来显示此 XML 文件中的条目。
该表格允许我编辑 2 个值(最小值和标称值)。 提交时,它将具有新值的 XML 内容保存到文件中,但是我只希望它在类别名称与 $_GET['cat'] 值匹配时保存数据。
我尝试了一些方法,但它仍然不断保存原始 XML 中的所有内容以及更新的值,而不是仅保存与类别名称匹配的数据。
这是我的代码:
if(isset($_POST))
{
$row = array();
$r = 0;
$catName = str_replace('.xml','',$_POST['catFile']); // Add change
foreach($_POST['row'] as $row)
{
$catFile = $_POST['catFile'];
$ufile = simplexml_load_file('newTypes2.xml');
foreach($ufile->type as $type)
{
if($type->category['name'] == $catName)
{
if($type['name'] == $_POST['item'][$r])
{
$type->nominal = $_POST['nominal'][$r];
$type->min = $_POST['min'][$r];
break;
}
file_put_contents($catFile, $ufile->asXML());
}
}
$r++;
}
}
表格如下:
if(!file_exists('newTypes2.xml'))
{
$xml = simplexml_load_file('types.xml');
} else {
$xml = simplexml_load_file('newTypes2.xml');
}
$json = json_encode($xml);
$array = json_decode($json,TRUE);
$cat = $_GET['cat'];
$i = 0;
$count = count($xml->type);
echo '<form class="form-horizontal" method="post" action="'.$_SERVER['PHP_SELF'].'">';
foreach($xml->type as $type)
{
if($cat == 'weapons')
{
if($type->category['name'] == "weapons")
{
$cnt = 0;
echo '<div class="form-group"><input type="hidden" name="row[]" value="'.$cnt.'"><input type="hidden" name="item[]" value="'.$type['name'].'">';
echo '<div class="col-md-4"><strong>'.$type['name'].'</strong></div> <div class="col-md-4">Nominal : <input class="form-control" type="text" value="'.$type->nominal.'" name="nominal[]"></div><div class="col-md-4">Minimum : <input type="text" class="form-control" value="'.$type->min.'" name="min[]"></div>';
echo '</div>';
$cnt++;
}
}
if($cat == 'tools')
{
if($type->category['name'] == "tools")
{
$cnt = 0;
echo '<div class="form-group"><input type="hidden" name="row[]" value="'.$cnt.'"><input type="hidden" name="item[]" value="'.$type['name'].'">';
echo '<div class="col-md-4"><strong>'.$type['name'].'</strong></div> <div class="col-md-4">Nominal : <input class="form-control" type="text" value="'.$type->nominal.'" name="nominal[]"></div><div class="col-md-4">Minimum : <input type="text" class="form-control" value="'.$type->min.'" name="min[]"></div>';
echo '</div>';
$cnt++;
}
}
if($cat == 'clothes')
{
if($type->category['name'] == "clothes")
{
$cnt = 0;
echo '<div class="form-group"><input type="hidden" name="row[]" value="'.$cnt.'"><input type="hidden" name="item[]" value="'.$type['name'].'">';
echo '<div class="col-md-4"><strong>'.$type['name'].'</strong></div> <div class="col-md-4">Nominal : <input class="form-control" type="text" value="'.$type->nominal.'" name="nominal[]"></div><div class="col-md-4">Minimum : <input type="text" class="form-control" value="'.$type->min.'" name="min[]"></div>';
echo '</div>';
$cnt++;
}
}
}
if(isset($_GET['cat']))
{
echo '<input type="hidden" name="catFile" value="'.$_GET['cat'].'.xml">';
echo '<button type="submit" class="btn btn-block btn-info">CHANGE</button></form>';
}
这里有一些示例 XML 数据:
<types>
<type name="AK74_WoodBttstck">
<nominal>5</nominal>
<lifetime>14400</lifetime>
<restock>0</restock>
<min>2</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
<category name="weapons"/>
<usage name="Military"/>
</type>
<type name="AKM">
<nominal>1</nominal>
<lifetime>7200</lifetime>
<restock>3600</restock>
<min>1</min>
<quantmin>30</quantmin>
<quantmax>80</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
<category name="weapons"/>
<usage name="ContaminatedArea"/>
</type>
<type name="AKS74U">
<nominal>17</nominal>
<lifetime>28800</lifetime>
<restock>0</restock>
<min>12</min>
<quantmin>30</quantmin>
<quantmax>80</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
<category name="weapons"/>
<usage name="Military"/>
<value name="Tier2"/>
<value name="Tier3"/>
<value name="Tier4"/>
</type>
<type name="SpearBone">
<nominal>0</nominal>
<lifetime>14400</lifetime>
<restock>0</restock>
<min>0</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="1" deloot="0"/>
<category name="tools"/>
</type>
<type name="SpearStone">
<nominal>0</nominal>
<lifetime>14400</lifetime>
<restock>0</restock>
<min>0</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="1" deloot="0"/>
<category name="tools"/>
</type>
<type name="Splint">
<nominal>0</nominal>
<lifetime>14400</lifetime>
<restock>0</restock>
<min>0</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="1" deloot="0"/>
<category name="clothes"/>
</type>
<type name="Splint_Applied">
<nominal>0</nominal>
<lifetime>3</lifetime>
<restock>0</restock>
<min>0</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="1" deloot="0"/>
<category name="clothes"/>
</type>
<type name="SportGlasses_Black">
<nominal>20</nominal>
<lifetime>14400</lifetime>
<restock>0</restock>
<min>10</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
<category name="clothes"/>
<tag name="shelves"/>
<usage name="Industrial"/>
<usage name="Town"/>
<usage name="Village"/>
<usage name="Office"/>
<usage name="School"/>
</type>
</types>
编辑: 应该只是添加,例如 $cat='tools',而不是只保存项目 它存储所有类型的项目
我之前想让脚本根据类别名称创建单独的 XML 文件。 如果有人能帮我解决这个问题,那就容易多了
使用
json_encode()
将 SimpleXMLElement 转换为 JSON 通常会导致数据丢失。这会序列化 SimpleXMLElement 实例的调试输出。
使用 XML API 访问/操作 XML。我更喜欢DOM+Xpath。这允许针对特定节点和任何类型的操作(SimpleXML 是一种抽象且有限)。
对于 DOM,首先创建并加载文档。
$original = __DIR__.'/types.xml';
$edited = __DIR__.'/newTypes.xml';
$allowedCategories = ['weapons', 'tools', 'clothes'];
$document = new DOMDocument();
$document->load(file_exists($edited) ? $edited : $original);
$xpath = new DOMXpath($document);
Xpath 实例可用于获取节点(作为节点列表)或标量值 从文档中。这就是表单输出的样子:
<html>
<body>
<form action="./" method="post">
<?php
// iterate the "type" elements
foreach ($xpath->evaluate('/types/type') as $typeNode) {
// fetch the first "name" attribute of the "category" element as a string
$category = $xpath->evaluate('string(category/@name)', $typeNode);
if (!in_array($category, $allowedCategories)) {
continue;
}
// read the name attribute of the current "type" element
$itemName = $typeNode->getAttribute('name');
// read the "nominal" child element as a number, cast to int
$nominal = (int)$xpath->evaluate('number(nominal)', $typeNode);
// read the "min" child element as a number, cast to int
$min = (int)$xpath->evaluate('number(min)', $typeNode);
// prepare the parameter name prefix - add "[someKey]" for each field
$fieldPrefix = 'items['.htmlspecialchars($itemName).']';
?>
<div class="form-group">
<div class="col-md-4"><strong><?=htmlspecialchars($itemName)?></strong></div>
<div class="col-md-4">Nominal : <input name="<?=$fieldPrefix?>[nominal]" class="form-control" type="text" value="<?=$nominal?>"></div>
<div class="col-md-4">Minimum : <input name="<?=$fieldPrefix?>[min]" class="form-control" type="text" value="<?=$min?>"></div>
</div>
<?php
}
?>
<button>Save</button>
</form>
</body>
</html>
PHP 会将像
items[someName1][someKey1]
这样的参数名称解析为嵌套关联数组结构。这允许删除隐藏字段并降低复杂性。
<?=...>
是 PHP 短标签语法。添加它是为了使 PHP 模板更具可读性。
现在,如果您提交表单,
$_POST
将包含一个可以迭代的嵌套结构(以下代码应位于表单输出之前)。
$modified = false;
// check for the "items" parameter
if (isset($_POST['items']) && is_array($_POST['items'])) {
// iterate it
foreach ($_POST['items'] as $name => $data) {
// fetch the "type" element with the matching "name" attribute
$typeNode = $xpath->evaluate('/types/type[@name="'.$name.'"]')[0];
// if found
if ($typeNode) {
// iterate the properties, use a whitelist
foreach (['min', 'nominal'] as $propertyName) {
// fetch the property node
$propertyNode = $xpath->evaluate($propertyName, $typeNode)[0];
// if node exists, data exists and the values are different
if (
$propertyNode &&
$data[$propertyName] &&
$propertyNode->textContent !== $data[$propertyName]
) {
// update node content with parameter data
$propertyNode->textContent = $data[$propertyName];
$modified = true;
}
}
}
}
// if a node was modified, save the document
if ($modified) {
$document->save($edited);
}
}