Элементы PHP SimpleXml для массива - PullRequest
1 голос
/ 30 октября 2009

Мне нужно отправить строку HTML имеет как <total> <tag>content</tag> <tag2 ref="333"> <code>somecode morecode </ Tag2> больше кода </ tag3>

Это будет в массив, как:

$arra[] = "<tag>content</tag>";
$arra[] = "<tag2 ref="333">";
$arra[] = "<code ... etc

Но я не понимаю, как преобразовать эти данные в массив.

Какие-нибудь советы?

Ответы [ 5 ]

2 голосов
/ 31 октября 2009

Что именно вы пытаетесь сделать? Если вы дадите более широкую картину проблемы, которую вы пытаетесь решить, мы сможем найти лучшее решение.

2 голосов
/ 31 октября 2009

Итак, вы хотите преобразовать эту древовидную структуру данных:

<total> 
  <tag>content</tag> 
  <tag2 ref="333"> 
    <code>somecode</code> 
    <code>morecode</code> 
  </tag2> 
  <tag3> more code </tag3> 
</total>

В какой-то плоский массив:

Array
(
    [0] => "<tag>content</tag>"
    [1] => "<tag2 ref="333"></tag2>"
    [2] => "<code>somecode</code>"
    [3] => "<code>morecode</code> 
    [4] => "<tag3> more code </tag3> "
)

было бы сложно. Это классическая проблема CS, которая не имеет много хороших ответчиков. Древовидная структура предоставляет информацию о связях между записями, которых нет у плоского массива или списка. Любая попытка свести дерево в список потеряет этот ссылочный контекст.

Вы можете либо взорвать строку, а затем пройти по ней, отслеживая родительские элементы или игнорируя их (см. Tag2). Если бы мне нужно было что-то сделать с xml, я бы бросил это в элемент SimpleXMLE, который бы выглядел примерно так:

SimpleXMLElement Object
(
    [tag] => content
    [tag2] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [ref] => 333
                )
            [code] => Array
                (
                    [0] => somecode
                    [1] => morecode
                )
        )
    [tag3] =>  more code 
)

С этим я могу пройтись по foreach и узнать тег и его содержимое. Я могу проверить, являются ли содержимое строками или дочерними элементами, и если да, то обойти их. Рекурсивная функция сделает эту задачу довольно короткой. Самая большая проблема заключается в том, как представить данные после их выравнивания.

Если вы сведете это в пример массива, который я предоставил ранее, родительские и дочерние теги теряют любые подразумеваемые отношения друг с другом. Если это не проблема, отлично. Напишите рекурсивную функцию и все готово. Вот некоторый псевдокод:

function walking($content)
  $out is the array chunk that is returned
  foreach $content as $tag->$data
    if $value is an SimpleXMLElement
      collapse $data[@attributes] into a string $attributes
      append <$tag $attributes></$tag> to the end of $out
      you may need to remove @attributes before recursing.
      recurse into  walking($data) and append the returned array to the end of $out
    if $value is an Array
      append <$tag></$tag> to the end of $out
      recurse into  walking($data) and append the returned array to the end of $out
    if $value is a string
      append <$tag>$value</$tag> to the end of $out
  after looping through $content return $out.

Однако, если вам нужно как-то сохранить эти отношения нетронутыми, у вас есть небольшая проблема, и вам нужно будет разработать какую-то схему для этого

2 голосов
/ 30 октября 2009

Просто:

$lines = explode('> ', $xml);
foreach($lines as $line) {
  $arra[] = $line.'> ';
}

Однако это предполагает, что данный пример является точным представлением вашего XML (т. Е. Вы используете> и <внутри блоков тегов) и не учитывает блоки CDATA или комментарии XML. <a href="http://www.w3.org/TR/REC-xml/#syntax" rel="nofollow noreferrer">http://www.w3.org/TR/REC-xml/#syntax

В противном случае я бы посмотрел комментарии на странице PHP.net: http://us.php.net/manual/en/function.xml-parse.php

0 голосов
/ 02 ноября 2009
$xml = file_get_contents("../../xml/LL1234.xml");

$x = simplexml_load_string($xml);

function viewElements($x){
    $Arr = $GLOBALS['Arr'];
    if (count($x->attributes()) > 0 ){
        $attr='';
        foreach ($x->attributes() as $k => $v ){
                $attr .= " $k='".$v."'";
        }
    }

    $Arr[] = "<".$x->getName()." $attr>\n";
    if (count($x->children()) > 0 ){
        foreach ($x->children() as $k ){
            $GLOBALS['Arr'] = $Arr;
            viewElements($k);
            $Arr = $GLOBALS['Arr'];
        }
    }else{
        $Arr[] = $x[0];
    }

    $Arr[] = "</".$x->getName().">";
    $GLOBALS['Arr'] = $Arr;
}

foreach ($x->children() as $k ){
    viewElements($k);
}

foreach ($GLOBALS['Arr'] as $k ){
    print $k."\n";
}
?>

Извините за беспокойство, благодаря tvanover. Я понял, что лучший способ сделать это - решение ниже.

0 голосов
/ 31 октября 2009

Если вы получаете данные из файла, то функция file () выдаст вам массив по одной строке на строку. Может быть самый простой способ!

...