2

I'm trying to transform XML into Json via PHP and I don't know how to serialize objects. Basically, I have in input an XML file (file.xml) with a recursive structure and I would like to transpose it into Json (out.json).

xml file sample:

<Transfer>
 <Name>Transfer</Name>
 <Title>Transfer + Date</Title>
 <Level1>
   <Name>Item 1</Name>
   <Title>Title 1</Title>
   <className>middle-level</className>
   <Level2>
      <Name>Item 1.1</Name>
      <Title>Title 1.1</Title>
      <className>product-dept</className>
   </Level2>
   <Level2>
      <Name>Item 1.2</Name>
      <Title>Title 1.2</Title>
      <className>product-dept</className>
      <Level3>
          <Name>Item 1.2.1</Name>       
          <Title>Title 1.2.1</Title>            
          <className>pipeline1</className>        
      </Level3>        
      <Level3>            
          <Name>Item 1.2.2</Name>            
          <Title>Title 1.2.2</Title>            
          <className>pipeline1</className>        
      </Level3>
    </Level2>  
  </Level1>  
  <Level1>    
    <Name>Item 2</Name>    
    <Title>Title 2</Title>    
    <className>middle-level</className>  
  </Level1>
</Transfer>

Json output desired :

{
    'name': 'Transfer',
    'title': 'transfer Date',
    'children': [
      { 'name': 'Item 1', 'title': 'Title 1', 'className': 'middle-level',
        'children': [
          { 'name': 'Item 1.1', 'title': 'Title 1.1', 'className': 'product-dept' },
          { 'name': 'Item 1.2', 'title': 'Title 1.2', 'className': 'product-dept',
            'children': [
              { 'name': 'Item 1.2.1', 'title': 'Title 1.2.1', 'className': 'pipeline1' },
              { 'name': 'Item 1.2.2', 'title': 'Title 1.2.2', 'className': 'pipeline1' },
            ]
          }
        ]
      },
      { 'name': 'Item 2', 'title': 'Title 2', 'className': 'middle-level'}
    ]
  }

All this with php code :

$xml = simplexml_load_file("file.xml");
$result = [];

foreach ($xml->Level1 as $value) 
{
    
    $child = [];
    $child['Name'] = (string)$value->Name;
    $child['Title'] = (string)$value->Title;
    $child['className'] = (string)$value->className;


    foreach ($xml->Level2 as $level2)
    {
        $child = [];
        $child['Level2'] = (string)$value->Level2->Name;
    }

    $result[] = $child;
    
}

$json_string = json_encode($result);
print_r($json_string);

Currently, I'm just transforming a part of the graph but I don't understand how to do more. I think that what I want to do is not too complex but I am blocked.

Thanks for the help.

2 Answers 2

1

When working with a structure of unkown depth, the stack is usually your best friend:

function xmlToJson($node, $level = 1)
{
    $children = [];
    if (isset($node->${'Level' . $level})) {
        foreach ($node->${'Level' . $level} as $value) {
            $children[] = [
                'name' => (string)$value->Name,
                'title' => (string)$value->Title,
                'className' => (string)$value->className,
                'children' => xmlToJson($value, $level + 1),
            ];
        }
    }

    return $children;
}

This code will start at level one and fetch all the names, titles and classNames. Then it calls itself, creating a recursive function. Because of this, you need to make sure that level exists, hence the if (isset(...)) before actually accessing the level.

The function will terminate if it stops calling itself, which is when there are no more levels to descent down to.

Sign up to request clarification or add additional context in comments.

Comments

0

Try this

    $xml = simplexml_load_string($xml);
    $result = [];
    $result['name'] = (string)$xml->Name;
    $result['title'] = (string)$xml->Title;

    foreach ($xml->Level1 as $value)
    {

        $child = [];
        $item = [];
        $item['name'] = (string)$value->Name;
        $item['title'] = (string)$value->Title;
        $item['className'] = (string)$value->className;

        foreach ($value->Level2 as $level2)
        {
            $child2 = [];
            foreach ($level2->Level3 as $level3) {
                $child2[] = array(
                    'name' => (string)$level3->Name,
                    'title' => (string)$level3->Title,
                    'className' => (string)$level3->className,
                );
            }
            $child[] = array(
                'name' => (string)$level2->Name,
                'title' => (string)$level2->Title,
                'className' => (string)$level2->className,
                'children' => $child2,
            );
        }

        $item['children'] = $child;
        $result['children'][] = $item;
    }
    $json_string = json_encode($result);
    print_r($json_string);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.