получение суммированных узлов вместо отдельных вложенных узлов

0

У меня есть сторонний XML файл, подобный этому. Это приложение для фильма, которое организует сцену, на которой снимается день съемки.

<schedule>

<DayBreak>
    <AutoText>true</AutoText>
    <Text></Text>
</DayBreak>

<Scene>
    81
</Scene>

<DayBreak>
    <AutoText>false</AutoText>
    <Text>myday</Text>
</DayBreak>

<Scene>
    82
</Scene>

<Scene>
    85
</Scene>

<schedule /> 

Как видите, наступает новый день, затем снимается сцена 81, затем наступает другой день, когда снимаются сцена 82 и сцена 85.

(Если вы спросите меня, я бы не структурировал xml, как это, но это то, что я получил от других парней.)

Теперь, если я проанализирую этот xml файл с помощью PHP simplexml, я получаю эти массивы:

                [DayBreak] => Array
                    (
                        [0] => SimpleXMLElement Object
                            (
                                [AutoText] => true
                                [Text] => SimpleXMLElement Object
                                    (
                                    )

                            )

                        [1] => SimpleXMLElement Object
                            (
                                [AutoText] => false
                                [Text] => myday
                            )
                        )

                [Scene] => Array
                    (
                        [0] => 81
                        [1] => 82
                        [2] => 85
                    )

                [EndShooting] => SimpleXMLElement Object
                    (
                    )

Как вы видите, я больше не могу разобрать, какая сцена снимается в тот день, когда массив суммируется.

Что мне делать?

спасибо, Мэтт

Теги:
simplexml

2 ответа

1
Лучший ответ

Одним из способов было бы перебрать дочерние узлы schedule сверху вниз, фиксируя XML на этом пути. Когда вы натыкаетесь на узел DayBreak, создайте новый узел контейнера Day в этом месте и поместите DayBreak в этот Day. Узлы Scene которые следуют за ними, также войдут в этот узел.

Таким образом, у вас будет лучшая структура для работы.

<?php
$xml = <<<END
<schedule>

<DayBreak>
    <AutoText>true</AutoText>
    <Text></Text>
</DayBreak>

<Scene>
    81
</Scene>

<DayBreak>
    <AutoText>false</AutoText>
    <Text>myday</Text>
</DayBreak>

<Scene>
    82
</Scene>

<Scene>
    85
</Scene>

</schedule>
END;
// Note: Last line in XML edited (used to be "<schedule />")

// Load
$dom = new DOMDocument();
$dom->loadXml($xml);

// Grab schedule node
$schedule = $dom->getElementsByTagName('schedule')->item(0);

// Loop through the child nodes of schedule
$i = 0;
while ($i < $schedule->childNodes->length) {
    $childNode = $schedule->childNodes->item($i);

    switch ($childNode->nodeName) {
        case 'DayBreak':
            $dayBreak = $childNode;
            // Brand new day. Wrap DayBreak node in Day node, into which the
            // following scene nodes will be moved
            $day = $dom->createElement('Day');
            $schedule->insertBefore($day, $dayBreak);
            $day->appendChild($dayBreak);
            break;

        case 'Scene':
            $sceneNode = $childNode;
            // A scene shot the current day. Move the node into the day node.
            $day->appendChild($childNode);
            continue 2; // Don't increase $i as node was moved out of 'schedule'
    }

    $i++;
}

// echo $dom->saveXML(); // Uncomment to view XML
var_dump(new SimpleXMLElement($dom->saveXML()));

Вывод:

object(SimpleXMLElement)#5 (1) {
  ["Day"]=>
  array(2) {
    [0]=>
    object(SimpleXMLElement)#6 (2) {
      ["DayBreak"]=>
      object(SimpleXMLElement)#9 (2) {
        ["AutoText"]=>
        string(4) "true"
        ["Text"]=>
        object(SimpleXMLElement)#10 (0) {
        }
      }
      ["Scene"]=>
      string(8) "
    81
"
    }
    [1]=>
    object(SimpleXMLElement)#8 (2) {
      ["DayBreak"]=>
      object(SimpleXMLElement)#9 (2) {
        ["AutoText"]=>
        string(5) "false"
        ["Text"]=>
        string(5) "myday"
      }
      ["Scene"]=>
      array(2) {
        [0]=>
        string(8) "
    82
"
        [1]=>
        string(8) "
    85
"
      }
    }
  }
}

редактировать

Затем вы можете прокручивать дни и сцены с помощью DOMDocument:

foreach ($dom->getElementsByTagName('Day') as $day) {
    echo "Day:";
    foreach ($day->getElementsByTagName('Scene') as $scene) {
        echo ' ' . trim($scene->nodeValue);
    }
    echo PHP_EOL;
}

или объект SimpleXMLElement, если вы более знакомы с этим:

$xml = new SimpleXMLElement($dom->saveXML());

foreach ($xml->Day as $day) {
    echo "Day:";
    foreach ($day->Scene as $scene) {
        echo ' ' . trim($scene);
    }
    echo PHP_EOL;
}

Выход (для примеров DOMDocument и SimpleXMLElement):

Day: 81
Day: 82 85
  • 0
    Спасибо! Это сделало трюк! Но как мне получить доступ к массиву «Scene» в моем объекте: object (SimpleXMLElement) # 12 (2) {["DayBreak"] => object (SimpleXMLElement) # 10 (2) {["AutoText"] => string ( 4) "true" ["Text"] => object (SimpleXMLElement) # 4 (0) {}} ["Scene"] => array (7) {[0] => string (1) "9" [1 ] => string (2) "72" [2] => string (3) "137" [3] => string (2) "93" [4] => string (2) "36" [5] = > string (3) "129" [6] => string (2) "24"}}
  • 0
    Смотрите мой отредактированный ответ с примерами того, как составить список сцен за день
0

Ты пробовал:

$xml = <<<xml
<schedule>

<DayBreak>
    <AutoText>true</AutoText>
    <Text></Text>
</DayBreak>

<Scene>
    81
</Scene>

<DayBreak>
    <AutoText>false</AutoText>
    <Text>myday</Text>
</DayBreak>

<Scene>
    82
</Scene>

<Scene>
    85
</Scene>

</schedule> 
xml;

$simpleXML = simplexml_load_string ($xml);

foreach ($simpleXML->children() as $node) {
    echo $node->getName().' = '.$node."\n";
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню