You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP使用XMLReader获取XML标签值并按营业时间生成新标签咨询

核心问题解决思路

  1. <opening_times>标签内存储的是标准JSON字符串,直接通过json_decode()即可提取所有营业时段、时区数据
  2. 你当前的XMLReader遍历逻辑已经可以获取单个offer节点的所有数据,只要在遍历循环内单独处理每个offer即可
  3. 原有时间比对函数存在2个问题:
    • 用了12小时制的date('h:i'),应该用24小时制的date('H:i')避免上下午判断错误
    • 没有适配<opening_times>里标注的时区,会导致时间判断偏差

完整实现代码

<?php
// 时间校验函数:传入解析后的opening_times数组,返回是否在营业时间内
function is_opening($opening_times_data) {
    // 先设置对应时区
    $timezone = new DateTimeZone($opening_times_data['timezone'] ?? 'Europe/Warsaw');
    $now = new DateTime('now', $timezone);
    // 获取当前周几(1=周一 到 7=周日,和JSON里的键对应)
    $current_day = $now->format('N');
    $current_time = $now->format('H:i');
    
    // 当天没有营业时段直接返回false
    if (empty($opening_times_data[$current_day])) {
        return false;
    }
    
    // 遍历当天所有营业时段判断
    foreach ($opening_times_data[$current_day] as $time_slot) {
        $opening = $time_slot['opening'];
        $closing = $time_slot['closing'];
        // H:i格式的时间字符串字典序和时间序一致,直接比较即可
        if ($current_time >= $opening && $current_time <= $closing) {
            return true;
        }
    }
    return false;
}

// 初始化XML读写
$reader = new XMLReader();
$reader->open('feed_sample.xml');
// 用DOMDocument生成新XML,保证CDATA格式正确
$new_xml = new DOMDocument('1.0', 'UTF-8');
$new_xml->formatOutput = true;
$offers_root = $new_xml->createElement('offers');
$new_xml->appendChild($offers_root);

// 遍历原XML的每个offer节点
while ($reader->read()) {
    if ($reader->name === 'offer' && $reader->nodeType == XMLReader::ELEMENT) {
        // 把单个offer节点转成DOMElement方便操作
        $offer_dom = dom_import_simplexml(simplexml_load_string($reader->readOuterXml()));
        // 导入到新XML文档
        $offer_node = $new_xml->importNode($offer_dom, true);
        
        // 提取opening_times的JSON内容解析
        $opening_times_str = $offer_node->getElementsByTagName('opening_times')->item(0)->nodeValue;
        $opening_times_data = json_decode($opening_times_str, true);
        
        // 计算is_active值
        $is_active = is_opening($opening_times_data) ? 'true' : 'false';
        // 创建带CDATA的is_active节点
        $is_active_node = $new_xml->createElement('is_active');
        $cdata = $new_xml->createCDATASection($is_active);
        $is_active_node->appendChild($cdata);
        // 把节点添加到offer下
        $offer_node->appendChild($is_active_node);
        
        // 把处理好的offer添加到新XML根节点
        $offers_root->appendChild($offer_node);
    }
}
$reader->close();

// 输出新XML文件
$new_xml->save('new_feed.xml');
?>

代码说明

  • 遍历原XML时每次循环内处理的就是单个offer节点,直接单独提取对应opening_times的值即可
  • 用DOMDocument生成新XML保证CDATA标签格式正确,不会出现转义错误
  • 时间判断用PHP的DateTime类适配指定时区,避免系统时区不同导致的判断错误

内容的提问来源于stack exchange,提问作者Kacper Woźniak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:54:03