【问题标题】:I want to edit an XML file using PHP我想使用 PHP 编辑 XML 文件
【发布时间】:2011-09-23 09:54:50
【问题描述】:

这是我的 XML 文件。

<body>
   <div>
     <p time="00:00:08"> </p>
     <p time="00:00:10"> </p>
     <p time="00:00:13"> </p>
   </div>
</body>

现在我想将 time = "00:00:12" 添加到 XML 文件中,但要按递增顺序。 所以,在添加这个时间之前,我必须将时间与其他时间进行比较,然后将其添加到适当的位置。

任何人都可以建议我如何做到这一点。一个示例代码会很有帮助。

【问题讨论】:

  • 您不需要在 XML 文件中有特定的顺序。对其进行排序是使用 XML 文件的代码的责任。
  • 实际上 JW 播放器将使用 xml 文件为视频添加字幕。在每个“时间”都会有一个字幕,由 JW 播放器播放。这就是我想要对 XML 文件进行排序的原因。
  • 是的,就像我说的,为 JWPlayer 预排序不是你的责任。 JWPlayer 必须按时间对 p 个元素进行排序。如果它不这样做,请向他们提交错误报告。顺便说一句,如果标题是有序的,为什么它们不在 OL 元素中呢?
  • 另外,根据W3 specs for Timed Text Markup Language (TTML) 1.0,p元素没有time属性。

标签: php xml


【解决方案1】:

按照Gordon's answer 中的建议,我会将 XML 文件加载到 SimpleXML 中,附加节点,然后对其进行排序。

我已经注释了下面的代码来一步一步地解释它。

<?php

// Open the XML file
$xml = file_get_contents("captions.xml");
// SimpleXml is an "easy" API to manipulate XML
// A SimpleXmlElement is any element, in this case it will be the <body> 
// element as it is first in the file.
$timestamps = new SimpleXmlElement($xml);

// Add our new time entry to the <div> element inside <body>
$timestamps->div->addChild("p", null);
// Get the index of the last element (the one we just added)
$index = $timestamps->div->p->count()-1;
// Add a time attribute to the element we just added
$e = $timestamps->div->p[$index];
$e->addAttribute("time", "00:00:12");
// Replace it with the new one (with a time attribute)
$timestamps->div->p[$index] = $e;

// Sort the elements by time (I've used bubble sort here as it's in the top of my head)
// Make sure you're setting this here or in php.ini, otherwise we get lots of warnings :)
date_default_timezone_set("Europe/London");

/**
 * The trick here is that SimpleXmlElement returns references for nearly
 * everything. This means that if you say $c = $timestamps->div->p[0], changes
 * you make to $c are made to $timestamps->div->p[0]. It's the same as calling
 * $c =& $timestamps->div->p[0]. We use the keyword clone to avoid this.
 */ 
$dates = $timestamps->div->children();
$swapped = true;
while ($swapped) {
    $swapped = false;
    for ($i = 0; $i < $dates->count() - 1; $i++) {
        $curTime = clone $dates[$i]->attributes()->time;
        $nextTime = clone $dates[$i+1]->attributes()->time;

        // Swap if current is later than next
        if (strtotime($curTime) > strtotime($nextTime)) {
            $dates[$i]->attributes()->time = $nextTime;
            $dates[$i+1]->attributes()->time = $curTime;
            $swapped = true;
            break;
        }
    }
}

// Write back
echo $timestamps->asXml();
//$timestamps->asXml("captions.xml");

【讨论】:

  • 我无法交换元素。
  • 我尝试使用 list( $timestamps->div[$i], $timestamps->div[$i+1]) = array( $timestamps->div[$i+1], $timestamps->div[$i])。还是不行
  • 嗯,我猜到了——会启动我的虚拟机并回复你。
  • 我修正了我的例子。由于冒泡排序损坏和大量解析错误应该教会我不要在头脑中编写代码:) 确保阅读有关引用的块注释(如果您不确定它们是什么,请在 PHP 手册中查找它们是)-它让我绊倒了一段时间(幸好我找到了http://stackoverflow.com/questions/1190026)。
  • 谢谢罗斯。该代码在我的本地主机上运行良好,但是当我尝试在我的 VPS 上运行它时,它一切正常,除了 $dates[$i]->attributes()->time = $nextTime; $dates[$i+1]->attributes()->time = $curTime;它们被 null ("") 覆盖。你能告诉我可能是什么问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多