PHP converte XML in JSON


158

Sto provando a convertire xml in json in php. Se eseguo una semplice conversione utilizzando xml e json_encode semplici nessuno degli attributi nello show xml.

$xml = simplexml_load_file("states.xml");
echo json_encode($xml);

Quindi sto cercando di analizzarlo manualmente in questo modo.

foreach($xml->children() as $state)
{
    $states[]= array('state' => $state->name); 
}       
echo json_encode($states);

e l'output per state è {"state":{"0":"Alabama"}}piuttosto che{"state":"Alabama"}

Che cosa sto facendo di sbagliato?

XML:

<?xml version="1.0" ?>
<states>
    <state id="AL">     
    <name>Alabama</name>
    </state>
    <state id="AK">
        <name>Alaska</name>
    </state>
</states>

Produzione:

[{"state":{"0":"Alabama"}},{"state":{"0":"Alaska"}

discarica var:

object(SimpleXMLElement)#1 (1) {
["state"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#3 (2) {
  ["@attributes"]=>
  array(1) {
    ["id"]=>
    string(2) "AL"
  }
  ["name"]=>
  string(7) "Alabama"
}
[1]=>
object(SimpleXMLElement)#2 (2) {
  ["@attributes"]=>
  array(1) {
    ["id"]=>
    string(2) "AK"
  }
  ["name"]=>
  string(6) "Alaska"
}
}
}

Includi uno snippet dell'XML e la struttura dell'array finale che hai dopo averlo analizzato. (A var_dumpfunziona benissimo.)
nikc.org il

aggiunto input, output e var_dump
Bryan Hadlock il

Alcune applicazioni richiedono "perfec XML-to-JSON map" , ovvero jsonML , vedere la soluzione qui .
Peter Krauss,

Risposte:


473

Json & Array da XML in 3 righe:

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

59
Questa soluzione non è perfetta. Elimina completamente gli attributi XML. Così <person my-attribute='name'>John</person>viene interpretato come <person>John</person>.
Jake Wilson,

13
$ xml = simplexml_load_string ($ xml_string, 'SimpleXMLElement', LIBXML_NOCDATA); per appiattire gli elementi cdata.
Txyoji,

28
@JakeWilson forse sono trascorsi 2 anni e varie correzioni di versione, ma su PHP 5.6.30, questo metodo produce TUTTI i dati. Gli attributi sono memorizzati nell'array sotto la @attributeschiave, quindi funziona in modo assolutamente perfetto e bello. 3 brevi righe di codice risolvono magnificamente il mio problema.
AlexanderMP,

1
Questo non funziona se hai più spazi dei nomi, puoi sceglierne solo uno, che passerà a $ json_string: '(
jirislav,

1
Tieni presente che con questa soluzione, quando potrebbero esserci più nodi con lo stesso nome, un nodo si tradurrà in una chiave che punta solo a un elemento, ma più nodi risulteranno in una chiave che punta alla matrice di elementi: <list><item><a>123</a><a>456</a></item><item><a>123</a></item></list>-> {"item":[{"a":["123","456"]},{"a":"123"}]}. Una soluzione su php.net di ratfactor risolve questo problema conservando sempre gli elementi in un array.
Klesun,

37

Ci scusiamo per aver risposto a un vecchio post, ma questo articolo delinea un approccio relativamente breve, conciso e facile da mantenere. L'ho provato io stesso e funziona abbastanza bene.

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;
    }
}
?>

4
Questo non funzionerà se hai più istanze dello stesso tag nel tuo XML, json_encode finirà per serializzare solo l'ultima istanza del tag.
ethree

35

L'avevo capito. json_encode gestisce gli oggetti in modo diverso rispetto alle stringhe. Ho lanciato l'oggetto su una stringa e ora funziona.

foreach($xml->children() as $state)
{
    $states[]= array('state' => (string)$state->name); 
}       
echo json_encode($states);

19

Immagino di essere un po 'in ritardo alla festa, ma ho scritto una piccola funzione per svolgere questo compito. Si occupa anche degli attributi, del contenuto del testo e anche se più nodi con lo stesso nome-nodo sono fratelli.

Dichiarazione di non responsabilità: non sono un nativo di PHP, quindi ti preghiamo di sopportare semplici errori.

function xml2js($xmlnode) {
    $root = (func_num_args() > 1 ? false : true);
    $jsnode = array();

    if (!$root) {
        if (count($xmlnode->attributes()) > 0){
            $jsnode["$"] = array();
            foreach($xmlnode->attributes() as $key => $value)
                $jsnode["$"][$key] = (string)$value;
        }

        $textcontent = trim((string)$xmlnode);
        if (count($textcontent) > 0)
            $jsnode["_"] = $textcontent;

        foreach ($xmlnode->children() as $childxmlnode) {
            $childname = $childxmlnode->getName();
            if (!array_key_exists($childname, $jsnode))
                $jsnode[$childname] = array();
            array_push($jsnode[$childname], xml2js($childxmlnode, true));
        }
        return $jsnode;
    } else {
        $nodename = $xmlnode->getName();
        $jsnode[$nodename] = array();
        array_push($jsnode[$nodename], xml2js($xmlnode, true));
        return json_encode($jsnode);
    }
}   

Esempio di utilizzo:

$xml = simplexml_load_file("myfile.xml");
echo xml2js($xml);

Esempio di input (myfile.xml):

<family name="Johnson">
    <child name="John" age="5">
        <toy status="old">Trooper</toy>
        <toy status="old">Ultrablock</toy>
        <toy status="new">Bike</toy>
    </child>
</family>

Esempio di output:

{"family":[{"$":{"name":"Johnson"},"child":[{"$":{"name":"John","age":"5"},"toy":[{"$":{"status":"old"},"_":"Trooper"},{"$":{"status":"old"},"_":"Ultrablock"},{"$":{"status":"new"},"_":"Bike"}]}]}]}

Abbastanza stampato:

{
    "family" : [{
            "$" : {
                "name" : "Johnson"
            },
            "child" : [{
                    "$" : {
                        "name" : "John",
                        "age" : "5"
                    },
                    "toy" : [{
                            "$" : {
                                "status" : "old"
                            },
                            "_" : "Trooper"
                        }, {
                            "$" : {
                                "status" : "old"
                            },
                            "_" : "Ultrablock"
                        }, {
                            "$" : {
                                "status" : "new"
                            },
                            "_" : "Bike"
                        }
                    ]
                }
            ]
        }
    ]
}

Stranezze da tenere a mente: diversi tag con lo stesso tagname possono essere fratelli. Molto probabilmente altre soluzioni lasceranno cadere tutto tranne l'ultimo fratello. Per evitare questo ogni singolo nodo, anche se ha solo un figlio, è un array che contiene un oggetto per ogni istanza del tagname. (Vedi più "" elementi nell'esempio)

Anche l'elemento radice, di cui solo uno dovrebbe esistere in un documento XML valido, viene archiviato come array con un oggetto dell'istanza, solo per avere una struttura dati coerente.

Per poter distinguere il contenuto del nodo XML e gli attributi XML, gli attributi di ciascun oggetto sono memorizzati in "$" e il contenuto nel figlio "_".

Modifica: ho dimenticato di mostrare l'output per i dati di input del tuo esempio

{
    "states" : [{
            "state" : [{
                    "$" : {
                        "id" : "AL"
                    },
                    "name" : [{
                            "_" : "Alabama"
                        }
                    ]
                }, {
                    "$" : {
                        "id" : "AK"
                    },
                    "name" : [{
                            "_" : "Alaska"
                        }
                    ]
                }
            ]
        }
    ]
}

Può analizzare dati XML di grandi dimensioni?
Volatil3

2
Questa soluzione è migliore perché non scarta gli attributi XML. Vedi anche perché questa struttura complessa è migliore di quelle semplificate, su xml.com/lpt/a/1658 (vedi "XML semi-strutturato") .... Ops, per CDATA, come suggerito da @txyoji per appiattire gli elementi CDATA $xml = simplexml_load_file("myfile.xml",'SimpleXMLElement',LIBXML_‌​NOCDATA);.
Peter Krauss,

Mille grazie per una funzione personalizzata! Rende il tuning abbastanza semplice. A proposito, è stata aggiunta una versione modificata della funzione che analizza XML in modo JS: ogni voce ha il suo oggetto (le voci non sono memorizzate in un singolo array se hanno tagname uguali), quindi l'ordine viene preservato.
lucifer63,

1
Errore Fatal error: Uncaught Error: Call to a member function getName() on bool.. penso che una versione php non riesca :-( .. per favore aiuto!
KingRider

10

Una trappola comune è dimenticare che json_encode()non rispetta gli elementi con un valore di testo e attributi. Sceglierà uno di quelli, che significa perdita di dati. La funzione seguente risolve questo problema. Se si decide di andare per json_encode/ decodeway, si consiglia la seguente funzione.

function json_prepare_xml($domNode) {
  foreach($domNode->childNodes as $node) {
    if($node->hasChildNodes()) {
      json_prepare_xml($node);
    } else {
      if($domNode->hasAttributes() && strlen($domNode->nodeValue)){
         $domNode->setAttribute("nodeValue", $node->textContent);
         $node->nodeValue = "";
      }
    }
  }
}

$dom = new DOMDocument();
$dom->loadXML( file_get_contents($xmlfile) );
json_prepare_xml($dom);
$sxml = simplexml_load_string( $dom->saveXML() );
$json = json_decode( json_encode( $sxml ) );

così facendo, <foo bar="3">Lorem</foo>non finirà come {"foo":"Lorem"}nel tuo JSON.


Non viene compilato e non produce l'output descritto se gli errori di sintassi vengono corretti.
Richard Kiefer,

Che cosa è $dom? Da dove viene?
Jake Wilson,

$ dom = new DOMDocument (); da dove viene
Scott,

1
Ultima riga di codice: $ json = json_decode (json_encode ($ sxml))); dovrebbe essere: $ json = json_decode (json_encode ($ sxml));
Charlie Smith,

6

Prova a usare questo

$xml = ... // Xml file data

// first approach
$Json = json_encode(simplexml_load_string($xml));

---------------- OR -----------------------

// second approach
$Json = json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA));

echo $Json;

O

È possibile utilizzare questa libreria: https://github.com/rentpost/xml2array


3

Ho usato il TypeConverter di Miles Johnson per questo scopo. È installabile utilizzando Composer .

Puoi scrivere qualcosa del genere usandolo:

<?php
require 'vendor/autoload.php';
use mjohnson\utility\TypeConverter;

$xml = file_get_contents("file.xml");
$arr = TypeConverter::xmlToArray($xml, TypeConverter::XML_GROUP);
echo json_encode($arr);

3

Ottimizzazione della risposta di Antonio Max:

$xmlfile = 'yourfile.xml';
$xmlparser = xml_parser_create();

// open a file and read data
$fp = fopen($xmlfile, 'r');
//9999999 is the length which fread stops to read.
$xmldata = fread($fp, 9999999);

// converting to XML
$xml = simplexml_load_string($xmldata, "SimpleXMLElement", LIBXML_NOCDATA);

// converting to JSON
$json = json_encode($xml);
$array = json_decode($json,TRUE);

4
Ho usato questo approccio, ma JSON è vuoto. XML è valido.
Ryabenko-pro,

2

Se desideri convertire solo una parte specifica dell'XML in JSON, puoi utilizzare XPath per recuperarlo e convertirlo in JSON.

<?php
$file = @file_get_contents($xml_File, FILE_TEXT);
$xml = new SimpleXMLElement($file);
$xml_Excerpt = @$xml->xpath('/states/state[@id="AL"]')[0]; // [0] gets the node
echo json_encode($xml_Excerpt);
?>

Si noti che se Xpath non è corretto, questo morirà con un errore. Quindi, se stai eseguendo il debug tramite chiamate AJAX, ti consiglio di registrare anche i corpi di risposta.


2
This is better solution

$fileContents= file_get_contents("https://www.feedforall.com/sample.xml");
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
$array = json_decode($json,TRUE);
return $array;

2

La migliore soluzione che funziona come un fascino

$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); // Remove // if you want to store the result in $json variable

echo '<pre>'.json_encode($simpleXml,JSON_PRETTY_PRINT).'</pre>';

fonte


1

Questo è un miglioramento della soluzione più votata di Antonio Max, che funziona anche con XML con spazi dei nomi (sostituendo i due punti con un carattere di sottolineatura). Ha anche alcune opzioni extra (e analizza <person my-attribute='name'>John</person>correttamente).

function parse_xml_into_array($xml_string, $options = array()) {
    /*
    DESCRIPTION:
    - parse an XML string into an array
    INPUT:
    - $xml_string
    - $options : associative array with any of these keys:
        - 'flatten_cdata' : set to true to flatten CDATA elements
        - 'use_objects' : set to true to parse into objects instead of associative arrays
        - 'convert_booleans' : set to true to cast string values 'true' and 'false' into booleans
    OUTPUT:
    - associative array
    */

    // Remove namespaces by replacing ":" with "_"
    if (preg_match_all("|</([\\w\\-]+):([\\w\\-]+)>|", $xml_string, $matches, PREG_SET_ORDER)) {
        foreach ($matches as $match) {
            $xml_string = str_replace('<'. $match[1] .':'. $match[2], '<'. $match[1] .'_'. $match[2], $xml_string);
            $xml_string = str_replace('</'. $match[1] .':'. $match[2], '</'. $match[1] .'_'. $match[2], $xml_string);
        }
    }

    $output = json_decode(json_encode(@simplexml_load_string($xml_string, 'SimpleXMLElement', ($options['flatten_cdata'] ? LIBXML_NOCDATA : 0))), ($options['use_objects'] ? false : true));

    // Cast string values "true" and "false" to booleans
    if ($options['convert_booleans']) {
        $bool = function(&$item, $key) {
            if (in_array($item, array('true', 'TRUE', 'True'), true)) {
                $item = true;
            } elseif (in_array($item, array('false', 'FALSE', 'False'), true)) {
                $item = false;
            }
        };
        array_walk_recursive($output, $bool);
    }

    return $output;
}

2
Non si utilizza Regex per analizzare XML, a meno che non sia un semplice XML con una struttura banale e dati molto prevedibili. Non posso sottolineare abbastanza quanto sia grave questa soluzione. Questo interrompe i dati. Per non parlare del fatto che è incredibilmente lento (analizzi regex e poi riesegui di nuovo?) E non gestisce i tag a chiusura automatica.
AlexanderMP,

Non penso che tu abbia davvero guardato la funzione. Non utilizza regex per eseguire l'analisi effettiva, solo come una semplice correzione per gestire gli spazi dei nomi - che ha funzionato per tutti i miei casi XML - e che funziona è il più importante, piuttosto che "politicamente corretto". Se vuoi, puoi migliorarlo!
TheStoryCoder

2
Il fatto che abbia funzionato per te non significa che sia giusto. È un codice come questo che genera bug immensamente difficili da diagnosticare e genera exploit. Intendo anche guardare superficialmente le specifiche XML su siti come questo w3schools.com/xml/xml_elements.asp mostrano molte ragioni per cui questa soluzione non funzionerebbe. Come ho detto, non riesce a rilevare tag autochiudenti come <element/>, non riesce a indirizzare elementi che iniziano con o contengono caratteri di sottolineatura, che è consentito in XML. Non riesce a rilevare CDATA. E come ho già detto, è LENTO. È una complessità O (n ^ 2) a causa dell'analisi interna.
AlexanderMP,

1
Il fatto è che non è stato nemmeno chiesto di occuparsi degli spazi dei nomi qui, e ci sono modi CORRETTI per gestire gli spazi dei nomi. Gli spazi dei nomi esistono come una costruzione utile, NON devono essere analizzati in questo modo e trasformati in un abominio che non verrà elaborato da nessun parser ragionevole. E tutto ciò che dovevi fare è non creare il contendente per il premio di "algoritmo più lento del 2016", ma fare un po 'di ricerca, trovare una miriade di soluzioni reali, come questa stackoverflow.com/ domande / 16412047 /… E per definirlo un miglioramento? Wow.
AlexanderMP,

0

Tutte le soluzioni qui hanno problemi!

... Quando la rappresentazione richiede una perfetta interpretazione XML (senza problemi con gli attributi) e per riprodurre tutto il testo-tag-testo-tag-testo -... e l'ordine dei tag. Inoltre, ricorda bene che l' oggetto JSON "è un set non ordinato" (non ripetere le chiavi e le chiavi non possono avere un ordine predefinito) ... Anche xml2json di ZF è sbagliato (!) Perché non conserva esattamente la struttura XML.

Tutte le soluzioni qui hanno problemi con questo semplice XML,

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

... La soluzione @FTav sembra migliore della soluzione a 3 righe, ma presenta anche piccoli bug quando viene testata con questo XML.

La vecchia soluzione è la migliore (per una rappresentazione senza perdite)

La soluzione, oggi nota come jsonML , è utilizzata dal progetto Zorba e altri, ed è stata presentata per la prima volta nel ~ 2006 o ~ 2007, da (separatamente) Stephen McKamey e 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);

Produrre

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

Vedi http://jsonML.org o github.com/mckamey/jsonml . Le regole di produzione di questo JSON si basano sull'elemento JSON-analogico,

inserisci qui la descrizione dell'immagine

Questa sintassi è una definizione di elemento e ricorrenza, con
element-list ::= element ',' element-list | element.


2
Struttura XML molto insolita che dubito avrebbe casi d'uso reali.
TheStoryCoder

0

Dopo aver ricercato un po 'tutte le risposte, ho trovato una soluzione che funzionava perfettamente con le mie funzioni JavaScript su tutti i browser (comprese console / strumenti di sviluppo):

<?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' ) );
 */

?>

Fondamentalmente crea un nuovo DOMDocument, carica e file XML in esso e attraversa ciascuno dei nodi e dei figli ottenendo i dati / parametri ed esportandolo in JSON senza i fastidiosi segni "@".

Collegamento al file XML .


0

Questa soluzione gestisce spazi dei nomi, attributi e produce risultati coerenti con elementi ripetitivi (sempre nella matrice, anche se si verifica una sola occorrenza). Ispirato da sxiToArray () di ratfactor .

/**
 * <root><a>5</a><b>6</b><b>8</b></root> -> {"root":[{"a":["5"],"b":["6","8"]}]}
 * <root a="5"><b>6</b><b>8</b></root> -> {"root":[{"a":"5","b":["6","8"]}]}
 * <root xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><a>123</a><wsp:b>456</wsp:b></root> 
 *   -> {"root":[{"xmlns:wsp":"http://schemas.xmlsoap.org/ws/2004/09/policy","a":["123"],"wsp:b":["456"]}]}
 */
function domNodesToArray(array $tags, \DOMXPath $xpath)
{
    $tagNameToArr = [];
    foreach ($tags as $tag) {
        $tagData = [];
        $attrs = $tag->attributes ? iterator_to_array($tag->attributes) : [];
        $subTags = $tag->childNodes ? iterator_to_array($tag->childNodes) : [];
        foreach ($xpath->query('namespace::*', $tag) as $nsNode) {
            // the only way to get xmlns:*, see https://stackoverflow.com/a/2470433/2750743
            if ($tag->hasAttribute($nsNode->nodeName)) {
                $attrs[] = $nsNode;
            }
        }

        foreach ($attrs as $attr) {
            $tagData[$attr->nodeName] = $attr->nodeValue;
        }
        if (count($subTags) === 1 && $subTags[0] instanceof \DOMText) {
            $text = $subTags[0]->nodeValue;
        } elseif (count($subTags) === 0) {
            $text = '';
        } else {
            // ignore whitespace (and any other text if any) between nodes
            $isNotDomText = function($node){return !($node instanceof \DOMText);};
            $realNodes = array_filter($subTags, $isNotDomText);
            $subTagNameToArr = domNodesToArray($realNodes, $xpath);
            $tagData = array_merge($tagData, $subTagNameToArr);
            $text = null;
        }
        if (!is_null($text)) {
            if ($attrs) {
                if ($text) {
                    $tagData['_'] = $text;
                }
            } else {
                $tagData = $text;
            }
        }
        $keyName = $tag->nodeName;
        $tagNameToArr[$keyName][] = $tagData;
    }
    return $tagNameToArr;
}

function xmlToArr(string $xml)
{
    $doc = new \DOMDocument();
    $doc->loadXML($xml);
    $xpath = new \DOMXPath($doc);
    $tags = $doc->childNodes ? iterator_to_array($doc->childNodes) : [];
    return domNodesToArray($tags, $xpath);
}

Esempio:

php > print(json_encode(xmlToArr('<root a="5"><b>6</b></root>')));
{"root":[{"a":"5","b":["6"]}]}

questo in realtà funziona per casi multi-namespace, meglio di altre soluzioni, perché ho ottenuto un voto
negativo

0

Ho trovato la risposta di FTav la più utile in quanto è molto personalizzabile, ma la sua funzione xml2js ha alcuni difetti. Ad esempio, se gli elementi figlio hanno nomi di nomi uguali, tutti verranno memorizzati in un singolo oggetto, ciò significa che l'ordine degli elementi non verrà conservato. In alcuni casi vogliamo davvero preservare l'ordine, quindi archiviamo meglio i dati di ogni elemento in un oggetto separato:

function xml2js($xmlnode) {
    $jsnode = array();
    $nodename = $xmlnode->getName();
    $current_object = array();

    if (count($xmlnode->attributes()) > 0) {
        foreach($xmlnode->attributes() as $key => $value) {
            $current_object[$key] = (string)$value;
        }
    }

    $textcontent = trim((string)$xmlnode);
    if (strlen($textcontent) > 0) {
        $current_object["content"] = $textcontent;
    }

    if (count($xmlnode->children()) > 0) {
        $current_object['children'] = array();
        foreach ($xmlnode->children() as $childxmlnode) {
            $childname = $childxmlnode->getName();
            array_push($current_object['children'], xml2js($childxmlnode, true));
        }
    }

    $jsnode[ $nodename ] = $current_object;
    return $jsnode;
}

Ecco come funziona. Struttura xml iniziale:

<some-tag some-attribute="value of some attribute">
  <another-tag>With text</another-tag>
  <surprise></surprise>
  <another-tag>The last one</another-tag>
</some-tag>

Risultato JSON:

{
    "some-tag": {
        "some-attribute": "value of some attribute",
        "children": [
            {
                "another-tag": {
                    "content": "With text"
                }
            },
            {
                "surprise": []
            },
            {
                "another-tag": {
                    "content": "The last one"
                }
            }
        ]
    }
}

-1

Sembra che la $state->namevariabile contenga un array. Puoi usare

var_dump($state)

all'interno del foreachper testarlo.

In tal caso, puoi modificare la linea all'interno di foreacha

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

per correggerlo.


sembra che gli attributi siano array ma non $ state-> name
Bryan Hadlock il

-1
$templateData =  $_POST['data'];

// initializing or creating array
$template_info =  $templateData;

// creating object of SimpleXMLElement
$xml_template_info = new SimpleXMLElement("<?xml version=\"1.0\"?><template></template>");

// function call to convert array to xml
array_to_xml($template_info,$xml_template_info);

//saving generated xml file
 $xml_template_info->asXML(dirname(__FILE__)."/manifest.xml") ;

// function defination to convert array to xml
function array_to_xml($template_info, &$xml_template_info) {
    foreach($template_info as $key => $value) {
        if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml_template_info->addChild($key);
                if(is_array($value)){
                    $cont = 0;
                    foreach(array_keys($value) as $k){
                        if(is_numeric($k)) $cont++;
                    }
                }

                if($cont>0){
                    for($i=0; $i < $cont; $i++){
                        $subnode = $xml_body_info->addChild($key);
                        array_to_xml($value[$i], $subnode);
                    }
                }else{
                    $subnode = $xml_body_info->addChild($key);
                    array_to_xml($value, $subnode);
                }
            }
            else{
                array_to_xml($value, $xml_template_info);
            }
        }
        else {
            $xml_template_info->addChild($key,$value);
        }
    }
}

È una soluzione piccola e universale basata su una matrice di dati può essere un JSON trasformato json_decode ... fortunato
Octavio Perez Gallegos,

2
In che modo risponde alla domanda originale? La tua risposta sembra più complicata della domanda originale e non sembra nemmeno menzionare JSON da nessuna parte.
Dan R,

-1

Se sei un utente Ubuntu, installa un lettore xml (ho php 5.6. Se ne hai altri, trova il pacchetto e installa)

sudo apt-get install php5.6-xml
service apache2 restart

$fileContents = file_get_contents('myDirPath/filename.xml');
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$oldXml = $fileContents;
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.