ZF-3257: Attributes or character data lost in Zend_Json::fromXml() in specific circumstances

Description

Example 1 - loss of character data

When a node's children are a mixture of character data and xml nodes, the character data is lost

$xml = 'bar'; echo Zend_Json::fromXml($xml, false);

Output: {"a":{"b":{"@attributes":{"id":"foo"}}}}

Example 2 - loss of attribute data

When a node has a single character data child, any attributes are lost

$xml = 'bar'; echo Zend_Json::fromXml($xml, false);

Output: {"a":{"b":"bar"}}

Comments

Please evaluate and fix/categorize as necessary.

What's the status on this? Seems like a pretty major problem.

What output would you expect in this case?

I dunno what the output should be, however I would suspect that the conversion should not loose any data. This is a pretty major issue and there needs to be a resolution.

Stas: In Example 1, note that the value of the "b" element, "bar", is not in the JSON representation. In Example2, the attribute "id" found in element "b" is not represented in the JSON.

I'm not entirely sure how you represent an XML element that has both attributes and values, but surely we need to be able to do so.

One example would be to create a special array index called "name" or"value" or etc. that would contain the element's info. This way it can coexist with the attributes index. This changes the data structure though but it's a special case and would need to be handled when converting back to xml.

My suggestion is to store the text value of a XML element using the key "@text" in the JSON format. The idea is to use the same logic of the @attributes JSON element. For instance, the following XML: bar can be represented in this JSON structure: {"a":{"b":{"@attributes":{"id":"foo"}},"@text":"bar"}} This should be the behaviour only in presence of "complex" XML elements (that means elements with attributes or sub-elements). For instance the following simple XML: foo will continue to be represented with the JSON string: {"a":"foo"}, instead of {"a":{"@text":"foo"}}

Resolved in branches/release-1.11 (commit 23971 and 23973)

With your changes in rev23915 $recursionDepth from _processXml is not recursion depth but the number of root-child-elements! Therefore you are not able to process a xml with more than 25 elements! The old one hat a additional $recursionDepth--; in line 331 which is missing in revision 23915

Simon thanks for the feedback. I used a $recursionDepth++ instead of $recursionDepth+1 in the recursive call (line 280). Resolved in trunk (commit 24039). Please test it and let me know, thanks.

Thanks for the very quick response and bugfix, Enrico! Now it works as expected.

Resolved in branches/release-1.11 (commit 24040)

Issued ZF2 pull request PR-356 to have changes pulled forward