【问题标题】:Appending data to xml file using php使用php将数据附加到xml文件
【发布时间】:2021-07-25 04:22:34
【问题描述】:

我是 xml 文件相关内容的新手。我遇到了一个问题。

我有一个 mysql 查询,它获取近 5000 行的 url 数据(1 行包含 1 个 url)。 所以我实现了一个 cron,它可以通过分页一次从 mysql 获取 1000 行。我需要对 url 进行一些验证,并且应该在 xml 文件中附加有效的 url。

这是我的代码

public function urlcheck()
    {
        $xFile = $this->base_path."sitemap/path/urls.xml";
        $page = 0;
        $cache_key = 'valid_urls';
        $page = $this->cache->redis->get($cache_key);
        if(!$page){
            $page=0;
        }

        $xFile = simplexml_load_file($xFile);

        $this->load->model('productnew/productnew_es6_m');
        $urls= $this->db->query("SELECT url FROM product_data where `active` = 1 limit ".$page.",1000")->result();

        $dom = new DOMDocument('1.0','UTF-8');
        $dom->formatOutput = true;      
        $root = $dom->createElement('urlset');
        $root->setAttribute('xsi:schemaLocation', 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd');
        $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        $root->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        $dom->appendChild($root);
        

        foreach($urls as $val)
        {   
            // validations here 
            $url = $dom->createElement('url');
            $root->appendChild($url);

            $lastmod = $dom->createElement('lastmod', date("Y-m-d"));
            $url->appendChild($lastmod);

            $page++;
        }

        $dom->saveXML();
        $dom->save($xFile) or die('XML Create Error');
        
        if(sizeof($urls) == 0){
            $page = 0;
        }
        print_r($page);
        $this->cache->redis->save($cache_key, $page, 432000);
        // echo '<xmp>'. $dom->saveXML() .'</xmp>';
        // $dom->saveXML();
        // $dom->save($xFile) or die('XML Create Error');
        
    }

在我第一次执行 cron 后,1000 个 url 中的 300 个有效 url 被保存到 xml 文件中, 现在让我们说在我的第二次 cron 执行中,我有 1000 个有效 url 中的 200 个。

我的预期结果是将这 200 个附加到现有的 xml 文件中,以便我的 xml 文件包含总共 500 个有效 url,并且如上所述,xml 文件应该在 5000 个 url 之后刷新。

但是每次执行 cron 后,旧的 url 数据都会被最新的一次替换。

我想知道如何在不覆盖 XML 的情况下保存 url 值。 提前谢谢你!

【问题讨论】:

  • 您使用simpleXML 加载文件,但使用DOMDocument 保存不同的文件
  • foreach($urls as $val) - $urls 来自哪里?
  • @ProfessorAbronsius 对不起,我现在更新了内容,我也尝试过使用 $dom->loadXML(xFile),但没有用
  • 对我来说看起来一样...你用simplexml_load_file($xFile) 打开$xFile ~ 然后创建一个新的DOMDocument 实例,做各种事情并将新文件保存为$xFile
  • 好的 - 花了一段时间,但我发现了变化......我的错!

标签: php xml simplexml xmldocument xmldom


【解决方案1】:

根据上面的评论,您使用一个 api (SimpleXML) 打开文件,但使用 DOMDocument 保存一个新文档 - 从而覆盖以前的工作。如果没有SimpleXML,也许你可以这样尝试——尽管它未经测试。

public function urlcheck(){
    
    $file=$this->base_path."sitemap/path/urls.xml";
    $cache_key='valid_urls';
    $page=$this->cache->redis->get($cache_key);
    
    if(!$page)$page=0;
    
    $dom=new DOMDocument('1.0','UTF-8');
    $dom->formatOutput = true;
    
    $col=$dom->getElementsByTagName('urlset');
    if( !empty( $col ) )$root=$col->item(0);
    else{
        $root=$dom->createElement('urlset');
        $dom->appendChild( $root );
        
        $root->setAttribute('xsi:schemaLocation','http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd');
        $root->setAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
        $root->setAttribute('xmlns','http://www.sitemaps.org/schemas/sitemap/0.9');     
    }
    
    # does a `page` node exist - if so use the value as the $page variable
    $col=$com->getElementsByTagName('page');
    if( !empty( $col ) )$page=intval( $col->item(0)->nodeValue );
    
    
    $this->load->model('productnew/productnew_es6_m');
    $urls=$this->db->query("SELECT `url` FROM `product_data` where `active` = 1 limit ".$page.",1000")->result();
    
    foreach( $urls as $val ){
        $url = $dom->createElement('url');
        $root->appendChild($url);

        $lastmod = $dom->createElement('lastmod', date("Y-m-d"));
        $url->appendChild($lastmod);

        $page++;
    }
    
    
    $node=$dom->createElement( 'page', $page );
    $root->insertBefore( $node, $root->firstChild );
    
    
    if( empty( $urls ) )$page=0;
    $dom->save( $file );
    $this->cache->redis->save( $cache_key, $page, 432000 );
}

【讨论】:

    【解决方案2】:

    附加到文档看起来不错,但是您并没有从磁盘上打开要附加到的文件。因此,在每个页面上,您从 XML 中的 0 个 url 开始并附加到空的根节点。

    但是每次执行 cron 后,旧的 url 数据都会被最新的一次替换。

    这正是您描述的行为,听起来您一开始并没有加载 XML 文件,只需编写它。

    所以问题可能是如何打开一个 XML 文件,按照您的描述追加看起来不错。

    让我们通过颠倒问题的介绍句来回顾一下:

    我需要对 url 进行一些验证,并且应该在 xml 文件中附加有效的 url。

    所以我实现了一个 cron,它通过分页从 mysql 中一次获取 1000 行。

    我有一个 mysql 查询,它获取近 5000 行的 url 数据(1 行包含 1 个 url)。

    假设每个 1000 个 url-set 附加到的文件已经在磁盘上(第 2-5 页),您需要附加。但是,如果第 1 页上的文件已经在磁盘上,您将附加到其他页面 1-5。

    所以看起来您只在第一页上编写了代码 - 以创建一个新文档(并附加到它)。

    尽管您提出问题,附加确实有效,但您自己编写:

    旧的 url 数据正在被最新的一次替换。

    唯一不起作用的是打开第 2 - 5 页的文件。

    所以让我们重新表述一下这个问题:如何打开 XML 文件?

    但首先,变量$page 并不代表page,如上面的第1-5 页。它只是一个名称有问题的变量,$page 代表循环中到目前为止处理的 URL 数量,而不是分页中的页面。

    不管它的名字是什么,我都会用它作为这个答案的价值。

    所以现在让我们在$page 不是0 时打开现有文档进行追加:

    ...
    
    $dom = new DOMDocument('1.0','UTF-8');
    $dom->formatOutput = true;
    
    if ($page !== 0) {
        $dom->load(dom_import_simplexml($xFile)->ownerDocument->documentURI)    ​
    }
    
    
    $col=$dom->getElementsByTagName('urlset');
    
    ...
    

    只有在第一次运行时,您才会有所描述的文件被创建新的行为 - 在这种情况下它很好(在第一次运行时 $page === 0)。

    在任何其他情况下,$page 不是 0,并且文件是从磁盘打开的。

    我已经单独留下了代码的其他部分,因此这个示例只介绍了这个 3 行 if 子句。

    load($file) 函数的文档可在 PHP 文档中找到,以防万一您到目前为止错过了它:

    如果您想跟上进度,请尽量不要重复使用相同的变量名称。在这里,我不得不回收整个 SimpleXMLElement 并将其导入 DOM 以获取打开文档的原始 xml 文件路径 - 尽管它曾经位于变量 $xFile 下,但它不再作为纯字符串提供。但这只是作为边缘的评论。

    由于您已经在使用 Redis,您可能希望将 URL 排队并从那里处理,那么您可能不需要数据库分页。见Lists of the Redis Data-Types

    然后,您还可以将好的 URL 放在第二个列表中。

    通过两个列表,您甚至可以直接在 Redis 中不断检查进度。

    当最终完成时,您可以在一个事务中从 Redis 中的好 URL 中一次性写入整个文件。

    如果您想在上面添加更多(最少)技术,请查看 Beanstalkd。

    【讨论】:

      猜你喜欢
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多