Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent result from single object to multiple objects of same element #2

Closed
pointybeard opened this issue Apr 25, 2016 · 4 comments
Assignees
Labels
Milestone

Comments

@pointybeard
Copy link
Owner

The resultant JSON differs depending if there is a single object or multiple of the same object.When there is only a single object (e.g. there is only 1 entry from a data-source), the result is a single object. However, when there is more than object of the same element (more than just 1 result from a data-source) the resultant JSON is an array.

Steps to reproduce

  1. Create a simple XML output with just a single entry
  2. Observe the JSON output
  3. Add another entry to the same output
  4. Observe the JSON again

Actual output

From XML like this:

<data>
  <entries>
    <entry>
      <id>2</id>
      <title>Another Entry</title>
      <handle>another-entry</handle>
      <body>Blah Blah</body>
      <publish-date>
        <date>2016-04-25</date>
        <time>19:03</time>
      </publish-date>
    </entry>
    <entry>
      <id>1</id>
      <title>An Entry</title>
      <handle>an-entry</handle>
      <body>This is a dummy entry</body>
      <publish-date>
        <date>2016-04-25</date>
        <time>16:53</time>
      </publish-date>
    </entry>
  </entries>
</data>

We get JSON like this:

{
    "entries": {
        "entry": [
            {
                "id": "2",
                "title": "Another Entry",
                "handle": "another-entry",
                "body": "Blah Blah",
                "publish-date": {
                    "date": "2016-04-25",
                    "time": "19:03"
                }
            },
            {
                "id": "1",
                "title": "An Entry",
                "handle": "an-entry",
                "body": "This is a dummy entry",
                "publish-date": {
                    "date": "2016-04-25",
                    "time": "16:53"
                }
            }
        ]
    }
}

However, remove 1 entry (so only 1 remains) and the output looks like this:

{
    "entries": {
        "entry": {
            "id": "1",
            "title": "An Entry",
            "handle": "an-entry",
            "body": "This is a dummy entry",
            "publish-date": {
                "date": "2016-04-25",
                "time": "16:53"
            }
        }
    }
}

Notice that the second example is not a JSON array.

Expected output

In both examples, it should be an array.

Possible solutions

It is possible the first behaviour is desirable since there will only ever be a single entry, this an array is unnecessary. One solution might be to have attributes on the XML e.g. forceArray="true" or similar which tells the JSON handler to behave in a certain way.

A stop-gap solution is to always include an empty element which tricks the parser into thinking it's an array. e.g.

<data>
  <entries>
    <entry>
      <id>2</id>
      <title>Another Entry</title>
      <handle>another-entry</handle>
      <body>Blah Blah</body>
      <publish-date>
        <date>2016-04-25</date>
        <time>19:03</time>
      </publish-date>
    </entry>
    <entry></entry>
  </entries>
</data>
    "entries": {
        "entry": [
            {},
            {
                "id": "1",
                "title": "An Entry",
                "handle": "an-entry",
                "body": "This is a dummy entry",
                "publish-date": {
                    "date": "2016-04-25",
                    "time": "16:53"
                }
            }
        ]
    },

However, this is not ideal.

@pointybeard pointybeard self-assigned this Apr 25, 2016
@brendo
Copy link

brendo commented Apr 25, 2016

Try fiddling with this line. If you flick the decode to treat convert objects into associative arrays you might get the desired result... I'm unsure if this is a deep conversion though, it might affect publish-date, eg. publish-date.date or publish-date[date].

@pointybeard
Copy link
Owner Author

I can understand why I get this result. Internally the SimpleXMLElement object looks like this:

SimpleXMLElement Object
(
    [entries] => SimpleXMLElement Object
        (
            [entry] => SimpleXMLElement Object
                (
                    [id] => 1
                    [title] => An Entry
                    [handle] => an-entry
                    [body] => This is a dummy entry
                    [publish-date] => SimpleXMLElement Object
                        (
                            [date] => 2016-04-25
                            [time] => 16:53
                        )
                )
        )

Compared to this when there is more than 1 "entry" element:

SimpleXMLElement Object
(
    [entries] => SimpleXMLElement Object
        (
            [entry] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                        )
                    [1] => SimpleXMLElement Object
                        (
                            [id] => 1
                            [title] => An Entry
                            [handle] => an-entry
                            [body] => This is a dummy entry
                            [publish-date] => SimpleXMLElement Object
                                (
                                    [date] => 2016-04-25
                                    [time] => 16:53
                                )
                        )
                )
        )

I've tried a few combinations with json_decode, however the result is always the same. Setting assoc (2nd parameter) to true unfortunately doesn't help. That just turns object(stdClass) into array.

I'm not sure it's quite possible to achieve what I want by manipulating the json_encode/decode process. Might have to perform a transformation on the array before using encode.

@pointybeard
Copy link
Owner Author

@pointybeard
Copy link
Owner Author

Pushed a potential fix. Also adds new feature "Transformers" (ce15331)

pointybeard pushed a commit that referenced this issue Apr 27, 2016
… Transformation classes. Updated CHANGELOG and README to reflect this change. Fixes #2
@pointybeard pointybeard added this to the 0.1.1 milestone Apr 27, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants