Конвертировать XML в JSON без атрибутов, используя PHP? - PullRequest
3 голосов
/ 01 февраля 2011

Я хочу конвертировать и XML файл в JSON с PHP. Файл XML выглядит следующим образом:

<content>
    <!-- other elements... -->
    <box id="1">
        <a>...</a>
        <b>...</b>
        <c>...</c>
    </box>
    <box id="2">
        <a>...</a>
        <b>...</b>
        <c>...</c>
    </box>
    <box id="3">
        <a>...</a>
        <b>...</b>
        <c>...</c>
    </box>
    <!-- more <box> elements... -->
    <!-- other elements... -->
</content>

Я использую этот простой скрипт PHP:

// Open XML file with SimpleXML.
$xml = simplexml_load_file('file.xml');
// Convert XML content to JSON.
$json = json_encode($xml);
// Output JSON.
echo $json;

Я получаю полное содержимое файла XML в виде вывода в формате JSON, однако мне нужно изменить скрипт на:

  • Получить только JSON для <box> элементы, а не полный файл.
  • Получить JSON без атрибутов элемента.

Это пример того, что я хочу получить в качестве вывода:

[{"a":"...","b":"...","c":"..."},
{"a":"...","b":"...","c":"..."},
{"a":"...","b":"...","c":"..."}]

Пожалуйста, помогите мне, как я могу это сделать? Какова лучшая практика?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 01 февраля 2011

Если имя узла (box) не меняется, вы можете использовать xpath:

$xml = simplexml_load_file('test.xml');
$arr = (array) $xml -> xpath('box');

... Но поскольку каждый box имеет id, этотк какому-то безумию:

$final = array();
foreach ($arr as $box) {
    $box = (array) $box;
    unset($box['@attributes']);
    $final[] = $box;
}

Я собирался искать лучший путь, но я начал видеть плавающий кинжал, поэтому я сдался.Таким образом, вам просто нужно json_encode массив $final.Godspeed.

1 голос
/ 22 ноября 2011

По сути, вам придется делать то, что другие респонденты предлагают и форматировать вывод JSON самостоятельно.

Это дает мне JSON, который я ищу - очень похожий на то, что вы хотите. Он рекурсивный, поэтому он будет работать для любого XML.

Этот XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <lss>
      <image type="Profile Image" part_id="11017" media="Image1.jpg" base="Image1" ext="jpg" width="128" height="96"/>
      <image type="Profile Image" part_id="11016" media="Image2.jpg" base="Image2" ext="jpg" width="180" height="225"/>
    </lss>

Отформатирован так:

  {
     "image":[
        {
           "type":"Profile Image",
           "part_id":"11017",
           "media":"Image1.jpg",
           "base":"Image1",
           "ext":"jpg",
           "width":"128",
           "height":"96"
        },
        {
           "type":"Profile Image",
           "part_id":"11016",
           "media":"Image2.jpg",
           "base":"Image2",
           "ext":"jpg",
           "width":"180",
           "height":"225"
        }
     ]
  }

Это может быть хорошо для вас, но если нет, вам нужно лишь слегка изменить $ final_tree, чтобы получить массив обнаженных "коробочных" объектов на верхнем уровне.

    function xml2json($xmlString)
    {   
        $start_tree = (array) simplexml_load_string(trim($xmlString));

        $final_tree = array();

        loopRecursivelyForAttributes($start_tree,$final_tree);

        return json_encode($final_tree);
    }   

    function loopRecursivelyForAttributes($start_tree,&$final_tree)
    {   
        foreach ($start_tree as $key1=>$row1)
        {   
            if(!array_key_exists($key1, $final_tree))
            {   
                $final_tree[$key1] = array();
            }   

            // If there is only one sub node, then there will be one less
            // array - ie: $row1 will be an array which has an '@attributes' key
            if(array_key_exists('@attributes', $row1))
            {   
                $row1 = (array) $row1;

                getValues($start_tree,$final_tree, $key1, $row1);
            }
            else
            {   
                foreach ($row1 as $row2)
                {   
                    $row2 = (array) $row2;

                    getValues($start_tree,$final_tree, $key1, $row2);
                }
            }
        }
    }

    function getValues($start_tree,&$final_tree, $key1, $row2)
    {   
        foreach ($row2 as $key3=>$val3)
        {   
            $val3 = (array) $val3;

            if($key3 == '@attributes')
            {   
                $final_tree[$key1][] = $val3;
            }
            else
            {   
                $temp_parent = array();

                $temp_parent[$key3] = $val3;

                loopRecursivelyForAttributes($temp_parent,$final_tree[$key1][count($final_tree[$key1])-1]);
            }
        }   
    }               
1 голос
/ 01 февраля 2011

Вы можете попробовать получить доступ к элементам по отдельности, например:

$boxes = array();
// Loop through each box element.
foreach($xml->box as $box) {
    // Add an array with the a, b, and c children.
    $boxes[] = array('a' => $box-> a, 'b' => $box->b, 'c' => $box->c);
}
$json = json_encode($boxes);

Это будет циклически проходить через каждый элемент box, извлекать теги a, b и c в массив, а затем кодировать JSON вместо объекта SimpleXML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...