0

(It has been suggested this question has already been answered here: PHP convert XML to JSON. But as detailed below I have already used simplexml_load_string which has not been successful).


I have tried multiple ways to get the content on an XML file to JSON, but the XML file is complex and fails with every attempt:

These are the methods I have tried:

$xml = \Zend\Xml2Json\Xml2Json::fromXml($data, false);

$doc = new \DOMDocument();
$doc->loadXML($data);
$x = $doc->documentElement;

$data = simplexml_load_string($data);

The result from the methods above:

{"Success":"true","FailMessage":{},"Returned_DataSet":{}}

I am looking to get the data from the result:

code: 47156
name: BARB
code: 1
name: GREATN
code: 89252
name: DERIN  

Here is the XML:

<?xml version="1.0" encoding="utf-8"?>
<DataSetResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://domain.co.uk/vehicles">
  <Success>true</Success>
  <FailMessage />
  <Returned_DataSet>
    <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
      <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="Table">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="CMan_Code" type="xs:int" minOccurs="0" />
                  <xs:element name="CMan_Name" type="xs:string" minOccurs="0" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
      <NewDataSet xmlns="">
        <Table diffgr:id="Table1" msdata:rowOrder="0">
          <CMan_Code>47156</CMan_Code>
          <CMan_Name>BARB                   </CMan_Name>
        </Table>
        <Table diffgr:id="Table2" msdata:rowOrder="1">
          <CMan_Code>1</CMan_Code>
          <CMan_Name>GREATN               </CMan_Name>
        </Table>
        <Table diffgr:id="Table3" msdata:rowOrder="2">
          <CMan_Code>89252</CMan_Code>
          <CMan_Name>DERIN                   </CMan_Name>
        </Table>
      </NewDataSet>
    </diffgr:diffgram>
  </Returned_DataSet>
</DataSetResult>
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
Paul
  • 2,465
  • 8
  • 35
  • 60
  • @jay-blanchard can remove your mark as duplicate from this question and read the problem properly. Thanks – Paul Aug 14 '19 at 12:38
  • Do not try to convert XML to JSON. Just read the data from the XML using Xpath: https://3v4l.org/3bIBk – ThW Aug 14 '19 at 12:44
  • Paul, you asked about conversion for which there are multiple duplicates. The answer isn't conversion to JSON. You must admit asking for conversion and not using conversion to answer the question seem opposed to each other. I am reopening, but this seems to be more of an [XY problem](http://xyproblem.info/) – Jay Blanchard Aug 14 '19 at 14:11
  • @JayBlanchard Thank you for your response and reopening the question. Granted there are other questions with solutions on this site, but as I had explained none of these worked. I assume you were not successful in getting any to work but I would have appreciated an example if you did. – Paul Aug 14 '19 at 16:09

1 Answers1

1

Generic conversion from XML to JSON fails for more complex XML. XML has attributes as an additional dimension, repeated nodes with the same name or mixed child nodes. JSON based formats like JsonML are possible, but that's not the JSON most people want or expect.

Try a different approach. Read values from the XML using Xpath (and DOM or SimpleXML methods). Build up the variables/data structures just as needed. You can then encode them as JSON.

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);

$items = [];
// iterate the Table nodes
foreach ($xpath->evaluate('//NewDataSet/Table') as $tableNode) {
    $items[] = [
        // read CMan_Code as string 
        'code' => trim($xpath->evaluate('string(CMan_Code)', $tableNode)),
        // read CMan_Name as string 
        'name' => trim($xpath->evaluate('string(CMan_Name)', $tableNode))
    ];
}

var_dump($items);

// encode the array variable as JSON
var_dump(json_encode($items, JSON_PRETTY_PRINT));
ThW
  • 19,120
  • 3
  • 22
  • 44