使用PHP

时间:2018-03-10 08:43:57

标签: php xml domdocument

我正在尝试使用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)。 dailytotalmonth属性表示。

我面临的问题是,当我在属于不同月份的日期(例如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"

1 个答案:

答案 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');