1

This is my XML file.

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

Now I want to add time = "00:00:12" to the XML file, but in increasing order. So, before adding this time, I will have to compare the time with other times and then add it at appropriate location.

Can anybody suggest me how to do this. A sample code would very helpful.

Poojan
  • 3,312
  • 4
  • 20
  • 23
  • possible duplicate of [A simple program to CRUD node and node values of xml file](http://stackoverflow.com/questions/4906073/a-simple-program-to-crud-node-and-node-values-of-xml-file) – Gordon Jun 27 '11 at 10:50
  • 2
    you dont need to have a specific order in the XML file. Sorting it is the responsibility of code consuming the XML file. – Gordon Jun 27 '11 at 10:50
  • actaully the xml file will be used by JW player for adding captions to the video. At each 'time' there will be a caption, which will be played by JW player. That is why I wanted to sort the XML file. – Poojan Jun 27 '11 at 10:54
  • yeah, like I said, it's not your responsibility to presort this for JWPlayer. JWPlayer has to sort the p elements by time. If it doesnt do that, file a bug report with them. On a sidenote, if the captions are in an ordered sequence, why are they not in an OL element instead? – Gordon Jun 27 '11 at 10:57
  • Also, according to the [W3 specs for Timed Text Markup Language (TTML) 1.0](http://www.w3.org/TR/2010/PR-ttaf1-dfxp-20100914/#content-vocabulary-p), there is no attribute `time` for p elements. – Gordon Jun 27 '11 at 11:11
  • yes, i know, I just wanted to give an example and did want to get into the details of the format of the DFXP captions file. – Poojan Jun 27 '11 at 11:28

1 Answers1

2

As was suggested in Gordon's answer, I would load the XML file into SimpleXML, append the node and then sort it.

I've commented the code below to explain it step-by-step.

<?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");
Community
  • 1
  • 1
Ross
  • 46,186
  • 39
  • 120
  • 173
  • i am unable to swap the elements. – Poojan Jun 28 '11 at 11:09
  • i tried using list( $timestamps->div[$i], $timestamps->div[$i+1]) = array( $timestamps->div[$i+1], $timestamps->div[$i]). Still it does not work – Poojan Jun 28 '11 at 11:13
  • Mm, I guessed that bit - will start up my VM and get back to you. – Ross Jun 28 '11 at 17:54
  • I fixed my example. With a broken bubble-sort and lots of parse errors should teach me not to code off the top of my head :) Make sure to read the block note about references (look them up in the PHP manual if you're not sure what they are) - it was tripping me up for a while (thankfully I found http://http://stackoverflow.com/questions/1190026). – Ross Jun 28 '11 at 21:50
  • Thanks Ross. The code works fine on my localhost, but when i try to run it on my VPS it everything works fine, except $dates[$i]->attributes()->time = $nextTime; $dates[$i+1]->attributes()->time = $curTime; They are overwritten by null (""). Can you tell me what might be the problem? – Poojan Jul 10 '11 at 07:26
  • Odd - do they both run the same version of PHP? Check the values of `$curTime` and `$nextTime` before they are put into `strtotime()`. It might also be to do with the default timezone used (which might change the locale, meaning dates are parsed differently). – Ross Jul 10 '11 at 20:37