PHP convert XML to JSON

前端 未结 20 1459
生来不讨喜
生来不讨喜 2020-11-22 06:25

I am trying to convert xml to json in php. If I do a simple convert using simple xml and json_encode none of the attributes in the xml show.

$xml = simplexml         


        
相关标签:
20条回答
  • 2020-11-22 07:13

    Sorry for answering an old post, but this article outlines an approach that is relatively short, concise and easy to maintain. I tested it myself and works pretty well.

    http://lostechies.com/seanbiefeld/2011/10/21/simple-xml-to-json-with-php/

    <?php   
    class XmlToJson {
        public function Parse ($url) {
            $fileContents= file_get_contents($url);
            $fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
            $fileContents = trim(str_replace('"', "'", $fileContents));
            $simpleXml = simplexml_load_string($fileContents);
            $json = json_encode($simpleXml);
    
            return $json;
        }
    }
    ?>
    
    0 讨论(0)
  • 2020-11-22 07:13

    I figured it out. json_encode handles objects differently than strings. I cast the object to a string and it works now.

    foreach($xml->children() as $state)
    {
        $states[]= array('state' => (string)$state->name); 
    }       
    echo json_encode($states);
    
    0 讨论(0)
  • 2020-11-22 07:14

    if you XML is a soap file, you can use this:

    $xmlStr = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $xmlStr);
    $xml = new SimpleXMLElement($xmlStr);
    return json_encode($xml);
    
    0 讨论(0)
  • 2020-11-22 07:18

    All solutions here have problems!

    ... When the representation need perfect XML interpretation (without problems with attributes) and to reproduce all text-tag-text-tag-text-... and order of tags. Also good remember here that JSON object "is an unordered set" (not repeat keys and the keys can't have predefined order)... Even ZF's xml2json is wrong (!) because not preserve exactly the XML structure.

    All solutions here have problems with this simple XML,

        <states x-x='1'>
            <state y="123">Alabama</state>
            My name is <b>John</b> Doe
            <state>Alaska</state>
        </states>
    

    ... @FTav solution seems better than 3-line solution, but also have little bug when tested with this XML.

    Old solution is the best (for loss-less representation)

    The solution, today well-known as jsonML, is used by Zorba project and others, and was first presented in ~2006 or ~2007, by (separately) Stephen McKamey and John Snelson.

    // the core algorithm is the XSLT of the "jsonML conventions"
    // see  https://github.com/mckamey/jsonml
    $xslt = 'https://raw.githubusercontent.com/mckamey/jsonml/master/jsonml.xslt';
    $dom = new DOMDocument;
    $dom->loadXML('
        <states x-x=\'1\'>
            <state y="123">Alabama</state>
            My name is <b>John</b> Doe
            <state>Alaska</state>
        </states>
    ');
    if (!$dom) die("\nERROR!");
    $xslDoc = new DOMDocument();
    $xslDoc->load($xslt);
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xslDoc);
    echo $proc->transformToXML($dom);
    

    Produce

    ["states",{"x-x":"1"},
        "\n\t    ",
        ["state",{"y":"123"},"Alabama"],
        "\n\t\tMy name is ",
        ["b","John"],
        " Doe\n\t    ",
        ["state","Alaska"],
        "\n\t"
    ]
    

    See http://jsonML.org or github.com/mckamey/jsonml. The production rules of this JSON are based on the element JSON-analog,

    This syntax is a element definition and recurrence, with
    element-list ::= element ',' element-list | element.

    0 讨论(0)
  • 2020-11-22 07:18

    Looks like the $state->name variable is holding an array. You can use

    var_dump($state)
    

    inside the foreach to test that.

    If that's the case, you can change the line inside the foreach to

    $states[]= array('state' => array_shift($state->name)); 
    

    to correct it.

    0 讨论(0)
  • 2020-11-22 07:20

    After researching a little bit all of the answers, I came up with a solution that worked just fine with my JavaScript functions across browsers (Including consoles / Dev Tools) :

    <?php
    
     // PHP Version 7.2.1 (Windows 10 x86)
    
     function json2xml( $domNode ) {
      foreach( $domNode -> childNodes as $node) {
       if ( $node -> hasChildNodes() ) { json2xml( $node ); }
       else {
        if ( $domNode -> hasAttributes() && strlen( $domNode -> nodeValue ) ) {
         $domNode -> setAttribute( "nodeValue", $node -> textContent );
         $node -> nodeValue = "";
        }
       }
      }
     }
    
     function jsonOut( $file ) {
      $dom = new DOMDocument();
      $dom -> loadXML( file_get_contents( $file ) );
      json2xml( $dom );
      header( 'Content-Type: application/json' );
      return str_replace( "@", "", json_encode( simplexml_load_string( $dom -> saveXML() ), JSON_PRETTY_PRINT ) );
     }
    
     $output = jsonOut( 'https://boxelizer.com/assets/a1e10642e9294f39/b6f30987f0b66103.xml' );
    
     echo( $output );
    
     /*
      Or simply 
      echo( jsonOut( 'https://boxelizer.com/assets/a1e10642e9294f39/b6f30987f0b66103.xml' ) );
     */
    
    ?>
    

    It basically creates a new DOMDocument, loads and XML file into it and traverses through each one of the nodes and children getting the data / parameters and exporting it into JSON without the annoying "@" signs.

    Link to the XML file.

    0 讨论(0)
提交回复
热议问题