XML Writer - 值多次保存?

时间:2017-05-01 08:51:31

标签: php xml

这是我的第一次XML和PHP结合练习,所以请在这里温柔:( 我在php中有一个normform,包含名称,城市,邮政编码等字段。每次用户完成编写并提交公式时,值应存储在xml文件中,并显示在网站上。 这是第一次,这非常好。但是如果我提交第二组值,我的xml开始看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE addressbook
SYSTEM "addressbook.dtd">
<addressbook>
 <entry>
 <name last="" first=""/>
 <address>
 <street>
  hallo
  hallo
  hallo
 </street>
 <zip>
  hallo
  hallo
  hallo
 </zip>
 <city>
  hallo
  hallo
  hallo
 </city>
 </address>
</entry>
<entry>
 <name last="hallo" first="hallo"/>
 <address>
 <street>hallo</street>
 <zip>hallo</zip>
 <city>hallo</city>
 </address>
</entry>

但实际上每个xml-entry片段应该看起来像较低的片段,并且不应该在那里以相乘的方式添加值? 这些是用于编写和读取xml的代码片段:

public function loadXMLFile(string $filename): array
{
    $data = [];

    if (file_exists($filename) && filesize($filename) != 0) {

        $XML_reader = new XMLReader();
        $XML_reader->open($filename, "UTF-8");
        $entry = null;
        $i = 0;

        while ($XML_reader->read()) {
            switch ($XML_reader->nodeType) {

                case XMLReader::ELEMENT:
                    switch ($XML_reader->name) {

                        case "addressbook":
                            $data = [];
                            break;

                        case "entry":
                            $data[$i] = null;
                            break;

                        case "name":
                            $data[$i]["lastName"] = $XML_reader->getAttribute("lastName");
                            $data[$i]["firstName"] = $XML_reader->getAttribute("firstName");
                            break;

                        case "address":
                            $data[$i]["city"] = $XML_reader->readString();
                            $data[$i]["zip"] = $XML_reader->readString();
                            $data[$i]["street"] = $XML_reader->readString();
                            break;
                    }

                    break;

                case XMLReader::END_ELEMENT:

                    if ($XML_reader->name === "entry") {
                        $i++;
                    }

                    break;
            }
        }

        $XML_reader->close();

    }

    return $data;

}


public function storeXMLValuesFromNormForm(string $filename, array $data): bool
{

    $filename = dirname($_SERVER["SCRIPT_FILENAME"]) . "/" . $filename;

    $XML_Writer = new XMLWriter();
    $XML_Writer->openUri($filename);
    $XML_Writer->setIndent(true);

    $XML_Writer->startDocument("1.0", "UTF-8");
    $XML_Writer->writeDtd("addressbook", null, "addressbook.dtd");

    $XML_Writer->startElement("addressbook");

    foreach ($data as $value) {

        $XML_Writer->startElement("entry");

        $XML_Writer->startElement("name");
        $XML_Writer->writeAttribute("last", $value['lastName']);
        $XML_Writer->writeAttribute("first", $value['firstName']);
        $XML_Writer->endElement();

        $XML_Writer->startElement("address");
        $XML_Writer->writeElement("street", $value['street']);
        $XML_Writer->writeElement("zip", $value['zip']);
        $XML_Writer->writeElement("city", $value['city']);
        $XML_Writer->endElement();

        $XML_Writer->endElement();

    }

    $XML_Writer->endElement();
    $XML_Writer->endDocument();
    $XML_Writer->flush();

    return true;

}

如果有人可以帮助我,那将是惊人的。我真的不知道是什么原因导致这一点的乘法增加。 要知道的另一件重要事情:如果我取消注释loadXMLFile函数,那么编写器就像它应该的那样编写XML部分 - 但只编写一次。每次提交公式时,都会覆盖这些值。当方法被激活时,这不会发生,但是,那么值会以某种方式成倍增加。

请帮帮我:(

1 个答案:

答案 0 :(得分:0)

当你找到地址元素......

 <address>
    <street>hallo</street>
    <zip>hallo</zip>
    <city>hallo</city>
 </address>

你做了以下事情:

case "address":
                            $data[$i]["city"] = $XML_reader->readString();
                            $data[$i]["zip"] = $XML_reader->readString();
                            $data[$i]["street"] = $XML_reader->readString();
                            break;

但是 - 你只找到了地址元素,而在XML中,此时文本的值也是所有子元素的文本。 您只能使用元素&#39; city&#39;一旦XML解析器读取了这些元素。因此,如果您在找到它们时存储这些元素的值

case "city":
    $city = $XML_reader->readString();

然后当你获得地址的 end element 时,你可以将这些值存储到你的数组中。