我正在尝试使用PHP动态生成/更新XML文件。以下是我想要的XML文件的结构:
test1.xml
<?xml version="1.0" encoding="UTF-8"?>
<month month_no="2">
<dailytotal date="2018-02-28">10</dailytotal>
<monthlytotal>10</monthlytotal>
</month>
dailytotal
元素存储每天的总值(由date
属性指示),monthlytotal
元素存储每个月的总值({{1}的总和}} S)。 dailytotal
由month
属性表示。
我面临的问题是,当我在属于不同月份的日期(例如month_no
)上生成XML文件时,文件将被覆盖,之前的所有内容都将消失。
我尝试搜索任何可能的问题(例如处理XML文档的DOM树)但我找不到任何问题,我的代码逻辑看起来是正确的!
此外,当我再次运行相同的脚本时,我收到一条警告信息,我无法理解为什么会得到它。
警告:DOMDocument :: load():文件末尾的额外内容:/ C:/xampp/htdocs/DailyExpenseCalculator/test1.xml,第6行:C:\ xampp \ htdocs \ DailyExpenseCalculator \第8行的xml_modify.php
我认为该警告是由于文件中有一个额外的换行符,但删除它并不起作用。
xml_generator.php
month_no="3"
答案 0 :(得分:2)
您需要一个根节点来放置<month>
标记。
首先,更改您的初始XML:
<?xml version="1.0" encoding="UTF-8"?>
<months>
<month month_no="2">
<dailytotal date="2018-02-28">10</dailytotal>
<monthlytotal>10</monthlytotal>
</month>
</months>
然后,在加载XML之后:
$months_tags = $doc->getElementsByTagName('months');
$months_tag = $months_tags[0];
最后,将月份标记放入根节点:
$months_tag->appendChild($newMonthElement);
完整代码:(检查/// <<< CHANGE
)
// Loading the XML file and updating data to it
$date = date('Y-m-d');
$balanceObj = 10;
$doc = new DOMDocument("1.0", "UTF-8");
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$doc->load('test1.xml');
$months_tags = $doc->getElementsByTagName('months'); /// <<< CHANGE
$months_tag = $months_tags[0]; /// <<< CHANGE
$months = $doc->getElementsByTagName('month');
$cur_month = (int) date('m');
$cur_date = $date;
$found_month = false;
echo "<p>Current date: ".$cur_date."</p>";
echo "<p>Current month: ".$cur_month."</p>";
foreach($months as $month) {
$month_no = (int) $month->getAttribute('month_no');
if($cur_month == $month_no) {
echo "<p>Found month</p>";
$dailytotals = $month->getElementsByTagName('dailytotal');
$found_date = false;
foreach($dailytotals as $d) {
$this_date = $d->getAttribute('date');
if($this_date === $cur_date) {
echo "<p>Found date</p>";
$new_dailytotal = $doc->createElement('dailytotal', (float) $balanceObj);
$new_dailytotal->setAttribute('date', $date);
$d->parentNode->replaceChild($new_dailytotal, $d); // (new node, old node)
$found_date = true;
break;
}
}
if($found_date == false) { // entry on a new day
echo "<p>Didn't found date</p>";
$newDailyTotal = $doc->createElement('dailytotal', (float) $balanceObj);
$newDailyTotal->setAttribute('date', $date);
$m = $month->getElementsByTagName('monthlytotal')->item(0);
$newBalance = ((float) $m->nodeValue) + ((float) $balanceObj);
$newMonthlyTotal = $doc->createElement('monthlytotal', (float) $newBalance);
$m->parentNode->replaceChild($newMonthlyTotal, $m);
$newDailyTotal = $month->appendChild($newDailyTotal);
}
else { // entry on the same day
$m = $month->getElementsByTagName('monthlytotal')->item(0);
// $oldBalance = (float) $m->nodeValue;
// $newBalance = $oldBalance - $oldDailyTotal + $balanceObj;
$newBalance = ((float) $m->nodeValue) + ((float) $balanceObj);
$newMonthlyTotal = $doc->createElement('monthlytotal', (float) $newBalance);
$m->parentNode->replaceChild($newMonthlyTotal, $m);
}
$found_month = true;
break;
}
}
if($found_month == false) {
echo "<p>Didn't found month</p>";
$newMonthElement = $doc->createElement('month');
$newMonthElement->setAttribute('month_no', $cur_month);
$newDailyTotalElement = $doc->createElement('dailytotal', 2);
$newDailyTotalElement->setAttribute('date', $date);
$newMonthlyTotalElement = $doc->createElement('monthlytotal', 3);
$newDailyTotalElement = $newMonthElement->appendChild($newDailyTotalElement);
$newMonthlyTotalElement = $newMonthElement->appendChild($newMonthlyTotalElement);
$months_tag->appendChild($newMonthElement); /// <<< CHANGE
}
$doc->save('test1.xml');