Estou tentando converter xml para json em php. Se eu fizer uma conversão simples usando xml simples e json_encode, nenhum dos atributos no show xml.
$xml = simplexml_load_file("states.xml");
echo json_encode($xml);
Então, eu estou tentando analisá-lo manualmente assim.
foreach($xml->children() as $state)
{
$states[]= array('state' => $state->name);
}
echo json_encode($states);
e a saída para estado é, em {"state":{"0":"Alabama"}}
vez de{"state":"Alabama"}
O que estou fazendo de errado?
XML:
<?xml version="1.0" ?>
<states>
<state id="AL">
<name>Alabama</name>
</state>
<state id="AK">
<name>Alaska</name>
</state>
</states>
Resultado:
[{"state":{"0":"Alabama"}},{"state":{"0":"Alaska"}
var dump:
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"
}
}
}
var_dump
funciona bem.)Respostas:
Json & Array do XML em 3 linhas:
fonte
<person my-attribute='name'>John</person>
é interpretado como<person>John</person>
.@attributes
chave, para que funcione de maneira absolutamente perfeita e bonita. Três pequenas linhas de código resolvem meu problema lindamente.<list><item><a>123</a><a>456</a></item><item><a>123</a></item></list>
->{"item":[{"a":["123","456"]},{"a":"123"}]}
. Uma solução no php.net pelo ratfactor resolve esse problema, sempre armazenando elementos em uma matriz.Desculpe por responder uma postagem antiga, mas este artigo descreve uma abordagem relativamente curta, concisa e fácil de manter. Eu mesmo testei e funciona muito bem.
http://lostechies.com/seanbiefeld/2011/10/21/simple-xml-to-json-with-php/
fonte
Eu descobri. O json_encode manipula objetos de maneira diferente das strings. Lancei o objeto a uma string e ele funciona agora.
fonte
Acho que estou um pouco atrasado para a festa, mas escrevi uma pequena função para realizar essa tarefa. Ele também cuida de atributos, conteúdo de texto e mesmo que vários nós com o mesmo nome de nó sejam irmãos.
Dislaimer: Eu não sou nativo do PHP, então, por favor, aceite erros simples.
Exemplo de uso:
Exemplo de entrada (myfile.xml):
Exemplo de saída:
Bastante impresso:
Peculiaridades a serem lembradas: várias tags com o mesmo nome de tag podem ser irmãos. É provável que outras soluções descartem todos, menos o último irmão. Para evitar isso, todo nó único, mesmo que tenha apenas um filho, é uma matriz que armazena um objeto para cada instância do tagname. (Veja vários "" elementos no exemplo)
Mesmo o elemento raiz, do qual apenas um deveria existir em um documento XML válido, é armazenado como matriz com um objeto da instância, apenas para ter uma estrutura de dados consistente.
Para poder distinguir entre o conteúdo do nó XML e os atributos XML, os atributos de cada objeto são armazenados no "$" e o conteúdo no filho "_".
Editar: esqueci de mostrar a saída para os dados de entrada de exemplo
fonte
$xml = simplexml_load_file("myfile.xml",'SimpleXMLElement',LIBXML_NOCDATA);
.Fatal error: Uncaught Error: Call to a member function getName() on bool
.. eu acho que uma versão php é deixar :-( .. por favor me ajude!Uma armadilha comum é esquecer que
json_encode()
não respeita elementos com um valor de texto e atributo (s). Ele escolherá um deles, significando dataloss. A função abaixo resolve esse problema. Se alguém optar pelo caminhojson_encode
/decode
, é recomendável a seguinte função.ao fazer isso,
<foo bar="3">Lorem</foo>
não terminará como{"foo":"Lorem"}
no seu JSON.fonte
$dom
? De onde isso veio?Tente usar isso
Ou
Você pode usar esta biblioteca: https://github.com/rentpost/xml2array
fonte
Eu usei o TypeConverter de Miles Johnson para esse fim. É instalável usando o Composer .
Você pode escrever algo assim usando:
fonte
Otimizando a resposta de Antonio Max:
fonte
Se você deseja converter apenas uma parte específica do XML em JSON, pode usar o XPath para recuperá-lo e convertê-lo em JSON.
Observe que, se o Xpath estiver incorreto, isso ocorrerá com um erro. Portanto, se você estiver depurando isso por meio de chamadas AJAX, recomendo que você também registre os corpos de resposta.
fonte
fonte
Melhor solução que funciona como um encanto
Fonte
fonte
Essa é uma melhoria da solução mais votada por Antonio Max, que também trabalha com XML que possui namespaces (substituindo os dois pontos por um sublinhado). Ele também possui algumas opções extras (e analisa
<person my-attribute='name'>John</person>
corretamente).fonte
<element/>
, falha em endereçar elementos que começam com ou contêm sublinhados, o que é permitido em XML. Falha na detecção do CDATA. E como eu disse, é LENTO. É uma complexidade O (n ^ 2) por causa da análise interna.Todas as soluções aqui têm problemas!
... Quando a representação precisar de perfeita interpretação XML (sem problemas com atributos) e reproduzir todo o texto-tag-text-tag-text -... e a ordem das tags. Também é bom lembrar aqui que o objeto JSON "é um conjunto não ordenado" (sem repetir chaves e as chaves não podem ter ordem predefinida) ... Até o xml2json da ZF está errado (!) Porque não preserva exatamente a estrutura XML.
Todas as soluções aqui têm problemas com este XML simples,
... A solução @FTav parece melhor que a solução de 3 linhas, mas também possui pouco bug quando testada com este XML.
A solução antiga é a melhor (para uma representação sem perdas)
A solução, hoje conhecida como jsonML , é usada pelo projeto Zorba e outros e foi apresentada pela primeira vez em ~ 2006 ou ~ 2007, por (separadamente) Stephen McKamey e John Snelson .
Produzir
Consulte http://jsonML.org ou github.com/mckamey/jsonml . As regras de produção deste JSON são baseadas no elemento JSON-analog,
Essa sintaxe é uma definição de elemento e recorrência, com
element-list ::= element ',' element-list | element
.fonte
Depois de pesquisar um pouco de todas as respostas, eu vim com uma solução que funcionava bem com minhas funções JavaScript nos navegadores (incluindo consoles / Ferramentas de desenvolvimento):
Ele basicamente cria um novo DOMDocument, carrega e arquivo XML nele e percorre cada um dos nós e filhos, obtendo os dados / parâmetros e exportando-os para JSON sem os sinais "@" irritantes.
Link para o arquivo XML .
fonte
Esta solução lida com namespaces, atributos e produz resultados consistentes com a repetição de elementos (sempre na matriz, mesmo se houver apenas uma ocorrência). Inspirado pelo sxiToArray () do ratfactor .
Exemplo:
fonte
A resposta do FTav foi a mais útil, pois é muito personalizável, mas sua função xml2js tem algumas falhas. Por exemplo, se os elementos filhos tiverem nomes de tag iguais, todos eles serão armazenados em um único objeto, isso significa que a ordem dos elementos não será preservada. Em alguns casos, realmente queremos preservar a ordem, para armazenar melhor os dados de cada elemento em um objeto separado:
Aqui está como isso funciona. Estrutura xml inicial:
JSON do resultado:
fonte
Parece que a
$state->name
variável está mantendo uma matriz. Você pode usardentro do
foreach
para testar isso.Se for esse o caso, você pode alterar a linha dentro de
foreach
parapara corrigi-lo.
fonte
fonte
Se você é um usuário do Ubuntu, instale o xml reader (eu tenho o php 5.6. Se você tiver outro, por favor encontre o pacote e instale)
fonte