【问题标题】:Check if Child is already in XML File检查 Child 是否已经在 XML 文件中
【发布时间】:2017-07-10 15:33:09
【问题描述】:

我有点卡在这里。对于具有不同地点的多个图标的 Google 地图,我需要 XML 格式的数据。这个想法是检查一个条目(由 Processwire 中的 ID 标识)是否已经在 XML 文件中。如果是,则无需做任何事情。如果不是,则必须将其添加到文件中。此外,如果 id 在 XML 文件上但不再在数据库上(因为它必须被删除),则需要将其删除。

这是我目前所拥有的:

$file = 'xml/markers.xml';
$xml = simplexml_load_file($file);

foreach ($pages->get('/produzenten/')->prod_repeater as $produzent) {               

$marker = $xml->addChild("marker");

$marker->addAttribute('id', $produzent->id);
$marker->addAttribute('name', $produzent->prod_name);
$marker->addAttribute('address', $produzent->prod_objekt . ', 8625 Gossau'  );               
$marker->addAttribute('type', $produzent->prod_kategorie);                
$marker->addAttribute('lat', $produzent->geo_lg);                
$marker->addAttribute('lng', $produzent->geo_bg);               

file_put_contents('xml/markers.xml', $xml->asXML());        
}

这可行,但每次调用网站时都会向文件中添加一大堆条目,这不是我想要的。

有什么帮助吗?

这是我们正在讨论的 XML 文件:Markers

【问题讨论】:

    标签: xml foreach attributes markers processwire


    【解决方案1】:

    您可以使用与访问数组或对象相同的语法简单地访问 xml 元素:

    $xml->someList[3]["someAttribute"];
    

    然后你当然可以比较值并决定做什么。

    为了测试,我稍微修改了你的代码,但我想你会明白的:
    (而且这可能不是最优雅的解决方案。idk)

    <?php
    $file = './markers.xml';
    $xml = simplexml_load_file($file);
    
    $prods = [
        [1, 'mark'],
        [2, 'anne'],
        [3, 'bernd'],
        [4, 'rose']
    ];
    
    foreach ($prods as $prod) {               
    
        $prodExists = false;
        foreach ($xml as $xmlMarker) {
            if($xmlMarker['id'] == $prod[0]) $prodExists = true;
        }
        if($prodExists) continue;
    
        $marker = $xml->addChild('marker');
        $marker->addAttribute('id', $prod[0]);
        $marker->addAttribute('name', $prod[1]);
    
    }
    
    file_put_contents('./markers.xml', $xml->asXML());
    

    您也可能不应该在循环中使用file_put_contents,您将在循环的每一次迭代中写入磁盘。而是在循环之后将文件写出一次。
    只要你-&gt;addChild() 一个新的孩子被添加到内存中的 xml 树中,你就可以虚拟地把它们堆积起来,直到你最终写出文件。

    编辑:

    哦...当然...您基本上只是想将 ProcessWire 数据中的所有 $prods 放入一个新的 XML 文件中(保留现有的 prods,添加新的,删除不存在的 => 只需将所有 prods 放在一个新文件)

    <?php
    
    $newXml = new SimpleXMLElement('<markers></markers>');
    
    $prods = $pages->get('/produzenten/')->prod_repeater;
    
    foreach($prods as $prod) {
        $marker = $xml->addChild("marker");
        $marker->addAttribute([...]); // all your attributes
    }
    
    file_put_contents('xml/markers.xml', $newXml->asXML());
    

    edit2:

    ...更好:

    创建一个新模板(例如 produzenten.xml.php)和一个将输出 xml 文件的页面(例如 produzenten.xml)。所以网址应该是这样的:www.domain.ch/produzenten/produzenten.xml

    这也可以缓存,如果“Produzenten”页面发生变化,您可以设置删除缓存的规则。

    模板文件可能是这样的:

    <?php
    
    header('Content-type: application/xml');
    echo '<?xml version="1.0" standalone="yes"?><markers>';
    
    foreach($pages->get('/produzenten/')->prod_repeater as $prod) {
        echo '<marker id="' . $prod->id . '" name="' . $prod->name . '"/>';
    }
    echo '</markers>';
    

    【讨论】:

    • 非常感谢,帮了大忙!但我仍然不知道如何检查一个 ID 是否只存在于 XML 文件中(不再存在于 CMS 端,因为已删除)。因此,XML 文件中的标记也应该被删除。
    • 嗯,你能在你的问题中展示一个 xml 文件的例子吗? (也许将其添加到问题中)
    • 我添加了文件
    • 呃——当然,我错过了那个——所以基本上你只想将 ProcessWire 中的所有产品放入一个新的 xml 文件中......对我的答案进行了编辑!希望有所帮助-尚未测试,但我认为您明白了;)
    • 谢谢,但我不能让它工作......另外,我不确定这是否是正确的方法......就像这样,每次网站获取时都会创建一个新文件加载,对吧?我以前尝试过类似的东西。如果网站上同时有几个人,有时数据没有加载...我希望添加或删除数据,只要有数据要添加或删除。如果 Processwire 中没有任何变化,则 XML 文件中也没有任何变化。那么,有没有办法检测一个项目是否被添加或删除?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2015-03-26
    • 2021-11-28
    • 1970-01-01
    相关资源
    最近更新 更多