1 Востаннє редагувалося Invader (27.10.2013 01:00:46)

Тема: Проблеми зі створенням XML

Існує функція яка викликається декілька разів і якій передаються два параметри. Функція, використовуючи ці параметри, має сформувати XML файл. Проблема полягає в тому як приєднати дані до DOM так щоб вони не дублювалися і коли дані для функції закінчаться записати XML в файл. Ось код:

$pubsFile = new DOMDocument("1.0", "UTF-8"); // об_єкт оголошено саме тут (і функція використовують 
// його як глобальний) для того щоб не створювати його наново при кожному виклику функції
$pubsFile->formatOutput = true;
$tmpPubsFile = '';

function parseRSS($rss) {
    global $pubsFile, $tmpPubsFile;
    foreach ($rss->channel->item as $e) {
        if ( stripos((string)$e->title[0], 'новые') !== false ) {
            writeRssData($e->pubDate, $e->description);
        }
    }
    $pubsFile = new DOMDocument();
    $pubsFile->loadXML($tmpPubsFile);
    $pubsFile->save(PUBS_FILE_NAME);
}

function writeRssData($pubDate, $description){
    global $pubsFile, $data, $pubsFileYears, $tmpPubsFile;
    $day = date('d', strtotime($pubDate));
    $month = date('F', strtotime($pubDate));
    $year = date('Y', strtotime($pubDate));
    if (isset($pubsFile->data)) {
        # open & read
        echo 'file';
    } else {
        if ($pubsFile->getElementById($pubDate) === NULL) {
            $data = $pubsFile->getElementsByTagName('data')->item(0);
            if (!$data) { // всі ці if'и потрібні для того щоб, якщо елемент існує, то не створювати його заново
                $data = $pubsFile->createElement("data");
                
            }
            $pubsFile->appendChild($data);

            $pubsFileYears = $pubsFile->getElementsByTagName('years')->item(0);
            if (!$pubsFileYears){
                $pubsFileYears = $pubsFile->createElement('years');
                $pubsFileYearsId = $pubsFile->createAttribute('id');
                $pubsFileYearsId->value = 'years';
                $pubsFileYears->value = $pubsFileYearsId;
                
            }
            $data->appendChild($pubsFileYears);

            $pubsFileYear = $pubsFile->getElementById($year);
            if (!$pubsFileYear) {
                $pubsFileYear = $pubsFile->createElement('year');
                $pubsFileYearId = $pubsFile->createAttribute('id');
                $pubsFileYearId->value = $year;
                $pubsFileYear->appendChild($pubsFileYearId);
            }
            $pubsFileYears->appendChild($pubsFileYear);

            $pubsFileMonth = $pubsFile->getElementById(date('m', strtotime($pubDate)).'.'.$year);
            if ($pubsFileMonth === NULL) {
                $pubsFileMonth = $pubsFile->createElement('month');
                $pubsFileMonthId = $pubsFile->createAttribute('id');
                $pubsFileMonthId->value = date('m', strtotime($pubDate)).'.'.$year;
                $pubsFileMonth->appendChild($pubsFileMonthId);
                
            }
            $pubsFileYear->appendChild($pubsFileMonth);

            $pubsFileDay = $pubsFile->createElement('day');
            $pubsFileDayId = $pubsFile->createAttribute('id');
            $pubsFileDayId->value = $day.'.'.date('m', strtotime($pubDate)).'.'.$year;
            $pubsFileDay->appendChild($pubsFileDayId);

            $pubsFileDescription = $pubsFile->createTextNode($description);
            $pubsFileDay->appendChild($pubsFileDescription);

            $pubsFileMonth->appendChild($pubsFileDay);

            $data->appendChild($pubsFileYears);

            $tmpPubsFile = $data->ownerDocument->saveXML(); // змінна $tmpPubsFile тут типу для накопичення
// даних щоб їх потім можна було записати. Вона глобальна і отже, не створюється кожного разу коли 
// викликається функція. Але, як видно нічого не накопичується.

// тут у мене була ідея тупо кожного разу перезаписувати глобальну змінну новим XML об_єктом,
// але вилазить помилка Uncaught exception 'DOMException' with message 'Wrong Document Error.
// При спробі імпортувати DOM щось їще вилазить. Зараз не можу перевірити.
            /*$pubsFile = new DOMDocument("1.0", "UTF-8");
            $tmpPubsFile = $pubsFile->importNode($data, TRUE);
            $pubsFile->appendChild($tmpPubsFile);*/
            #$pubsFile->loadXML($tmpPubsFile);

Мав би, в результаті роботи програми, виникнути отака структура:

<data>
    <years>
        <year id="2013">
            <month id="10.2013">
                <day id="23.10.2013">Text here</day>
                <day id="22.10.2013">Text here</day>
            </month>
            <month id="10.2013">
                <day id="23.10.2013">Text here</day>
                <day id="22.10.2013">Text here</day>
            </month>
        </year>
    </years>
</data>

але виходить отаке:

<data>
    <years>
        <year id="2013">
            <month id="10.2013">
                <day id="23.10.2013">Text here</day>
            </month>
        </year>
        <year id="2013">
               <month id="10.2013">
                   <day id="22.10.2013">Text here</day>
                </month>
         </year>
    </years>
</data>

2 Востаннє редагувалося Invader (27.10.2013 01:12:23)

Re: Проблеми зі створенням XML

Поясню ще так: є список публікацій. Кожна така публікація має текст і дату. Потрібно з цього списку сформувати XML з якого було зручно отримувати публікації за датами. Як таке зробити?

3

Re: Проблеми зі створенням XML

По-перше, треба надавати мінімальний робочий код. Вігдадування, в якій послідовності і як саме викликаються дві функції (при тому, що в поясненні сказано "існує функція" в однині), що таке $data (чи треба йому бути глобальним) і чи закінчується writeRssData  на один рядок нижче за наведений код, а чи за 50 рядків нижче - це вкрай цікаво на "Битві телепатів" (чи як там те шоу зветься), але якщо ви хочете отримати допомогу - трохи потрудіться зробити своє питання вичерпним.
По-друге, весь код по додаванню дати виконується за умови

 if ($pubsFile->getElementById($pubDate) === NULL) {

яка, вочевидь, не виконується, якщо вже є елемент з id $pubDate.

4 Востаннє редагувалося Invader (27.10.2013 10:57:50)

Re: Проблеми зі створенням XML

КОд на pastebin.com

По-друге, весь код по додаванню дати виконується за умови

    if ($pubsFile->getElementById($pubDate) === NULL) {

яка, вочевидь, не виконується, якщо вже є елемент з id $pubDate.

Так задумано. Для уникнення дублікатів.

5 Востаннє редагувалося koala (27.10.2013 14:38:30)

Re: Проблеми зі створенням XML

Invader написав:

Мав би, в результаті роботи програми, виникнути отака структура:

                <day id="23.10.2013">Text here</day>
                <day id="22.10.2013">Text here</day>

але виходить отаке:

                <day id="23.10.2013">Text here</day>
Invader написав:

Так задумано. Для уникнення дублікатів.

Я ще маю тут щось дописувати?