5

I have an XML file where some tags occasionally may be empty. When I read this file using PHP and encode it using json_encode, JSON converts all my empty tags to empty objects, while I prefer them exactly as they are - empty strings. What is the best way to stop /avoid this conversion?

EDIT: I prefer not to delete these tags from XML as for me there is a difference between an XML entry without specific tag and an XML entry with this tag being empty.

EDIT 2: sample input:

<Family>
  <name>aaa</name> 
  <adults>3</adults>
  <kids />
</Family>

kids tag is empty

I would like to get encoding results as

Family[1].name = 'aaa';
Family[1].adults = 3;
Family[1].kids = '';

What I am getting is:

Family[1].name = 'aaa';
Family[1].adults = 3;
Family[1].kids = Object(); //empty

EDIT3:

My implementation is very simple:

in PHP

$xml = simplexml_load_file($filepath);
echo json_encode($xml, JSON_NUMERIC_CHECK);

in JavaScript

    objJson = $.parseJSON(xmlhttp.responseText);
        ....
        d["name"] = objJson.Family[i].name;
        d["adults"] = objJson.Family[i].adults;
        d["kids"] = objJson.Family[i].kids;
5
  • Whar do you mean empty? Blank or with root tags? Commented Oct 18, 2012 at 21:49
  • Would it be possible to post some sample input and desired outputs so what we can see exactly what you mean? Commented Oct 18, 2012 at 21:50
  • can you post sample of json structure Commented Oct 18, 2012 at 21:51
  • 2
    Can you show your conversion implementation from XML to json Commented Oct 18, 2012 at 21:53
  • Can you change the XML to <kids><kids/>? Commented Oct 18, 2012 at 22:07

2 Answers 2

4

You can try

$xml = '<Family>
    <name>aaa</name>
    <adults>3</adults>
    <kids />
    <sub>
        <tag>Nice </tag>
        <tag>Food </tag>
        <tag />
    </sub>
</Family>';

$xml = new SimpleXMLElement($xml);
$json = json_encode($xml, JSON_NUMERIC_CHECK);
$json = json_decode($json, true);

var_dump($json); // Before

filterEmptyArray($json); // <------ Filter Empty Array

var_dump($json); // After

Before

array
  'name' => string 'aaa' (length=3)
  'adults' => int 3
  'kids' => 
    array   <------------------- Empty Array
      empty
  'sub' => 
    array
      'tag' => 
        array
          0 => string 'Nice ' (length=5)
          1 => string 'Food ' (length=5)
          2 => 
            array 
              ...

After

array
  'name' => string 'aaa' (length=3)
  'adults' => int 3
  'kids' => string '' (length=0) <---------- String Conversion
  'sub' => 
    array
      'tag' => 
        array
          0 => string 'Nice ' (length=5)
          1 => string 'Food ' (length=5)
          2 => string '' (length=0) <---------- Supports Recursion (2nd level) 

Function Used

function filterEmptyArray(array &$a) {
    foreach ( $a as $k => &$v ) {
        if (empty($v))
            $a[$k] = "";
        else
            is_array($v) AND filterEmptyArray($v);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

That is more or less the way I am doing it now. The problem is that the XML file could be pretty big, and there could be a lot of them, so there are performance issues.
How big are we taking about .. can you put such file in paste bin lets run some benchmark
On the second thought I am going to accept your answer, i just can do it inside my main iteration loop, where I am going through all the records anyway. Thanks.
Is there a way to do the same thing while returning stdObjects as my code is expecting std classes not the arrays ?
Worked for me. its not the most amazing solution but I wrote a recursive walk to manipulate the data inside simplexmlelement hierarchy and by turning this into a JSON object, turning it back into an array, then stripping all the rubbish out of the array then back into JSON worked well. NOTE you do need to do the mod that tombombadilll suggested or you will replace any integer 0's with an empty string.
1

I think the function filterEmptyArray() above needs an addition to it to dont delete zeros as values. Eg. 0 will also become ''

if (empty($v) && is_array($v))
    $a[$k] = "";
}

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.