Português (Brasil)

Ferramentas de desenvolvedor · Conversores de sintaxe

Mapeamento de XML para JSON: atributos, nós de texto e o problema um-contra-muitos

· Como funciona

xml JSON formatos de dados

Um item XML mapeado para um objeto enquanto itens repetidos são mapeados para uma matriz
Ilustração vetorial original ToolAcre

Não existe uma única maneira correta de transformar XML em JSON, porque XML possui atributos, conteúdo misto e filhos ordenados que faltam em JSON. Esta postagem explica as convenções de mapeamento comuns e as armadilhas de cada uma.

Por que um <item> se tornou um objeto e dois se tornaram um array — o feed XML cujo formato JSON muda dependendo de quantas entradas ele possui

Um feed com `<item>one</item>` produz `"item": "one"`; adicionar um segundo irmão altera essa propriedade para `"item": ["one", "two"]`. O analisador não pode inferir que um item era conceitualmente uma lista de um porque ambos os significados têm sintaxe XML idêntica. O código criado apenas com base na primeira amostra pode, portanto, falhar quando a produção enviar a segunda.

ToolAcre não esconde essa instabilidade atrás de uma opção sempre array. Ele registra um nome uma vez como um valor e irmãos repetidos como uma matriz. Esse mapeamento direto é fácil de inspecionar, mas os consumidores que precisam de um formato de coleção estável devem usar o conhecimento do esquema ou normalizar o resultado após a conversão.

O que XML tem e JSON não tem — atributos, texto misturado com elementos, irmãos ordenados, namespaces, comentários e instruções de processamento

XML separa atributos de elementos filhos, preserva a ordem dos irmãos, permite texto entre elementos, carrega prefixos de namespace e pode conter comentários e instruções de processamento. JSON oferece objetos e arrays, mas não possui equivalentes integrados para essas categorias de nós. Qualquer resultado XML-to-JSON é, conseqüentemente, uma projeção escolhida, não uma tradução universal.

Este leitor descarta a declaração, comentários e instruções de processamento. Os prefixos de namespace permanecem textuais em vez de serem resolvidos: `<ns:item>` se torna a chave `ns:item`, enquanto `xmlns:ns` se torna `@xmlns:ns`. O texto misto é unido em uma chave, portanto, sua posição original em torno dos elementos filhos é perdida e um aviso informa que a conversão não pode ser ida e volta.

Convenções de atributos — prefixos como @ ou $, por que existem e como um atributo e um elemento filho com o mesmo nome colidem

Os atributos usam um prefixo `@`. `<user id="7"><id>other</id></user>` torna-se um objeto com `@id` igual a `"7"` e filho `id` igual a `"other"`. O prefixo evita que duas construções XML diferentes colidam em uma única propriedade de objeto. Também se torna parte do contrato do conversor quando JSON é gravado de volta em XML.

Outras bibliotecas podem usar `$`, um objeto de atributos ou outra convenção. ToolAcre oferece suporte apenas ao mapeamento `@` visível. Alterar esse prefixo no código do aplicativo sem alterar o gravador transformaria atributos em elementos, portanto, preserve-o ao usar o valor convertido como um formulário de inspeção intermediário.

Convenções de nós de texto — #text ou _ para conteúdo de elemento e o que acontece quando um elemento tem texto e filhos

Um elemento contendo apenas texto é recolhido nessa string. Quando atributos ou filhos também estão presentes, o texto fica sob `#text`; CDATA é mantido separadamente em `#cdata`. Uma tag de fechamento automático torna-se uma string vazia. Essas chaves reservadas permitem ao escritor distinguir nomes filhos comuns de categorias de conteúdo que o próprio JSON não define.

O conteúdo misto permanece com perdas. Em `<p>before<b>bold</b>after</p>`, a posição de “antes” e “depois” em relação ao filho não pode ser reconstruída a partir de uma propriedade `#text` unida. A ferramenta detecta esse padrão estrutural e avisa. Use um XML API que preserva o nó quando a ordem do documento fizer parte do significado.

O problema de um contra muitos – elementos repetidos tornando-se matrizes apenas quando repetidos, e por que os consumidores devem codificar defensivamente

Irmãos repetidos se transformam em arrays somente após a repetição ser observada. Um único `<book>` é um objeto; dois livros são uma série de objetos. Isso às vezes é chamado de problema de um contra muitos, mas não é um defeito do analisador. O documento fonte simplesmente não contém uma declaração de lista independente de suas ocorrências.

Consumidores defensivos podem normalizar caminhos conhecidos com conhecimento de esquema: agrupar `catalogue.book` quando ainda não for um array. Não aplique essa regra a todas as propriedades, porque um escalar comum não deve se tornar uma lista apenas por simetria. O conversor evita deliberadamente inventar tais informações de domínio.

Exemplo resolvido: convertendo um pequeno documento no estilo RSS - atributos, um elemento repetido e um namespace, com o JSON resultante anotado

Converter `<feed xmlns:m="https://example.invalid/meta"><item id="1"><m:title>One</m:title></item><item id="2"><m:title><![CDATA[Two & More]]></m:title></item></feed>`. A raiz é `feed`; `@xmlns:m` retém a declaração do namespace; `item` é uma matriz; cada `@id` é texto; e o segundo título contém `#cdata`.

A inferência de tipo está desativada por padrão, portanto, mesmo `id="2"` permanece a string `"2"`. Habilitar a inferência permite que o analisador leia texto numérico e booleano como aqueles tipos JavaScript, mas XML não declarou essa intenção. A opção é uma suposição controlada pelo usuário, e não uma evidência fornecida pelo documento.

O que isso não cobre — conversão orientada por esquema que sabe que um elemento é sempre uma lista, o que requer um XSD ou um mapeamento manual

Nenhum XSD foi carregado e nenhuma informação de lista orientada por esquema está disponível. O conversor não pode saber se um elemento é repetível quando apenas um aparece, validar os filhos necessários, resolver URIs de namespace em tipos de aplicativos ou gerar um cliente digitado. Uma análise bem-sucedida estabelece apenas XML bem formado e aceito pelo leitor configurado.

As declarações DOCTYPE são recusadas antes da análise, incluindo as inofensivas. Esse limite impede solicitações de entidades externas, leituras de arquivos locais e expansão de entidades. A remoção de um DOCTYPE também pode remover declarações das quais o documento dependia, portanto, faça isso somente quando você possuir os dados e compreender as consequências.

Conclusão: XML para JSON é um mapeamento, não uma tradução - e como o painel Conversores de sintaxe permite inspecionar esse mapeamento em seu navegador

Trate o resultado como o mapeamento documentado de ToolAcre: `@` para atributos, `#text` para texto de elemento misto, `#cdata` para CDATA, matrizes após irmãos repetidos e prefixos de namespace literais. Essas regras tornam a saída previsível sem fingir que XML e JSON compartilham um modelo de dados.

Para inspeção, esta projeção é rápida e legível. Para uma integração durável, teste uma e muitas ocorrências, atributos que compartilham nomes com filhos, elementos vazios, conteúdo misto e namespaces. Se a ordem dos elementos ou as restrições do esquema forem importantes, analise XML em relação a esse contrato, em vez de depender de uma forma genérica convertida.

Mantenha o fixture XML bruto ao lado da expectativa normalizada. Esse emparelhamento preserva evidências se uma atualização de dependência alterar o tratamento de array, corte de espaços em branco ou decodificação de entidade. Também oferece aos revisores um local para ver as distinções que a visualização JSON não pode realizar. Um objeto convertido sozinho não pode provar se uma string vazia veio de um elemento de fechamento automático, de tags emparelhadas ou de outra convenção na origem.