Issues

ZF-12224: Zend_Json::fromXml creates empty json string

Description

I have extracted an xml (xmp) string from a jpeg photo and successfully loaded it to create a DOMDocument in php. When I export the xml string from the DOMDocument (using $xmlstring = $xmldocument->saveXML()) and try to create a json string using Zend_Json::fromXml($xmlstring), I get the following "empty" json string: {"RDF":""}

Same thing happens when I use the xml string directly (ie without loading to a DOMDocument first). There aren't many recursion levels in the string (2 or 3) and I'm able to manipulate the DOMDocument in php without any issues.

Comments

Can you post the XML string here?

Here's the xml string:

www.w3.org/1999/02/22-rdf-syntax-ns#"> 123000000/100003000000/10000

     <tiff:ResolutionUnit>2</tiff:ResolutionUnit>
     <tiff:Make>NIKON CORPORATION</tiff:Make>
     <tiff:Model>NIKON D200</tiff:Model>
     <tiff:NativeDigest>256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;B47C241E53ED5D64CA700180D73CEC2B</tiff:NativeDigest>
  </rdf:Description>
  <rdf:Description xmlns:xap="http://ns.adobe.com/xap/1.0/" rdf:about="">
     <xap:ModifyDate>2006-09-08T16:55:07-04:00</xap:ModifyDate>

     <xap:CreatorTool>Adobe Photoshop CS2 Windows</xap:CreatorTool>
     <xap:CreateDate>2006-08-29T09:42:26-04:00</xap:CreateDate>
     <xap:MetadataDate>2006-09-08T16:55:07-04:00</xap:MetadataDate>
  </rdf:Description>
  <rdf:Description xmlns:exif="http://ns.adobe.com/exif/1.0/" rdf:about="">
     <exif:ExifVersion>0221</exif:ExifVersion>
     <exif:FlashpixVersion>0100</exif:FlashpixVersion>

     <exif:CompressedBitsPerPixel>4/1</exif:CompressedBitsPerPixel>
     <exif:PixelXDimension>800</exif:PixelXDimension>
     <exif:PixelYDimension>536</exif:PixelYDimension>
     <exif:DateTimeOriginal>2006-08-29T09:42:26-04:00</exif:DateTimeOriginal>
     <exif:DateTimeDigitized>2006-08-29T09:42:26-04:00</exif:DateTimeDigitized>
     <exif:ExposureTime>10/1000</exif:ExposureTime>

     <exif:FNumber>56/10</exif:FNumber>
     <exif:ExposureProgram>2</exif:ExposureProgram>
     <exif:ExposureBiasValue>0/6</exif:ExposureBiasValue>
     <exif:MaxApertureValue>41/10</exif:MaxApertureValue>
     <exif:MeteringMode>2</exif:MeteringMode>
     <exif:LightSource>0</exif:LightSource>

     <exif:FocalLength>520/10</exif:FocalLength>
     <exif:SensingMethod>2</exif:SensingMethod>
     <exif:FileSource>3</exif:FileSource>
     <exif:SceneType>1</exif:SceneType>
     <exif:CustomRendered>0</exif:CustomRendered>
     <exif:ExposureMode>0</exif:ExposureMode>

     <exif:WhiteBalance>0</exif:WhiteBalance>
     <exif:DigitalZoomRatio>1/1</exif:DigitalZoomRatio>
     <exif:FocalLengthIn35mmFilm>78</exif:FocalLengthIn35mmFilm>
     <exif:SceneCaptureType>0</exif:SceneCaptureType>
     <exif:GainControl>0</exif:GainControl>
     <exif:Contrast>0</exif:Contrast>

     <exif:Saturation>0</exif:Saturation>
     <exif:Sharpness>0</exif:Sharpness>
     <exif:SubjectDistanceRange>0</exif:SubjectDistanceRange>
     <exif:GPSVersionID>0.0.2.2</exif:GPSVersionID>
     <exif:ISOSpeedRatings>
        <rdf:Seq>
           <rdf:li>100</rdf:li>

        </rdf:Seq>
     </exif:ISOSpeedRatings>
     <exif:Flash rdf:parseType="Resource">
        <exif:Fired>False</exif:Fired>
        <exif:Return>0</exif:Return>
        <exif:Mode>0</exif:Mode>
        <exif:Function>False</exif:Function>

        <exif:RedEyeMode>False</exif:RedEyeMode>
     </exif:Flash>
     <exif:ColorSpace>-1</exif:ColorSpace>
     <exif:NativeDigest>36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;47A06DE371320245089B1A1DAA388AC7</exif:NativeDigest>
  </rdf:Description>
  <rdf:Description xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/" rdf:about="">
     <xapMM:DocumentID>uuid:EABB739A6F3FDB11AB45EE04CB17DD9C</xapMM:DocumentID>

     <xapMM:InstanceID>uuid:8911EA4E7C3FDB11AB45EE04CB17DD9C</xapMM:InstanceID>
  </rdf:Description>
  <rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/" rdf:about="">
     <dc:format>image/jpeg</dc:format>
     <dc:creator>
        <rdf:Seq>
           <rdf:li>Matt Turner</rdf:li>

        </rdf:Seq>
     </dc:creator>
     <dc:title>
        <rdf:Alt>
           <rdf:li xml:lang="x-default">maine boat</rdf:li>
        </rdf:Alt>
     </dc:title>
     <dc:subject>

        <rdf:Bag>
           <rdf:li>boat</rdf:li>
           <rdf:li>reflection</rdf:li>
           <rdf:li>row</rdf:li>
           <rdf:li>wood</rdf:li>
        </rdf:Bag>
     </dc:subject>

  </rdf:Description>
  <rdf:Description xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" rdf:about="">
     <photoshop:ColorMode>3</photoshop:ColorMode>
     <photoshop:AuthorsPosition>Mr</photoshop:AuthorsPosition>
     <photoshop:History/>
  </rdf:Description>

Thanks for looking at this. Not too sure about the answer you found though. When I step through the code, the problem seems to be in the _processXml function in Zend/Json.php. In that function the $children variable doesn't work for the example above (and perhaps anytime namespaces are used?).

When namespaces are used, I think you would need to start with one of the following: //either get all namespaces used at once //the below would return an array of 8 namespaces for the above xml: rdf, tiff, xap, exif, xapMM, dc, xml, photoshop $ns = $simpleXmlElementObject->getNamespaces(true);

//or to start with just the top level namespace //the below would return an array with a single namespace for the above xml: rdf $ns = $simpleXmlElementObject->getNamespaces();

//then get children by iterating through the namespaces //for the above xml, the below would return 6 children for the rdf namespace foreach($ns as $namespace => $url) { $children = $simpleXmlElementObject->children($namespace, true); }

With the existing code, $children is 0, which seems to be the reason an empty string is returned.

The answer you linked to suggested the colons in the xml tags caused a problem in SimpleXML. Not sure what problem is being referred to - the colons signify the use of namespaces and SimpleXML can easily return the part before the colon (the namespace), or the part after (the name). Thanks again for your help. lindon

I don't think this is a problem with SimpleXML. The comp.lang.php discussion linked above is very old, possibly from before SimpleXML supported namespaced elements which it definitely does do now as explained by @lindon.

It would be very useful if Zend_Json could handle namespaces.