Qual é a maneira correta de representar elementos XML nulos?

166

Vi nullelementos representados de várias maneiras:

O elemento está presente com xsi:nil="true":

 <book>
     <title>Beowulf</title>
     <author xsi:nil="true"/>
 </book>

O elemento está presente, mas representado como um elemento vazio (que eu acredito estar errado desde 'vazio' e nullé semanticamente diferente):

 <book>
     <title>Beowulf</title>
     <author/>
 </book>

 <!-- or: -->
 <book>
     <title>Beowulf</title>
     <author></author>
 </book>

O elemento não está presente na marcação retornada :

 <book>
     <title>Beowulf</title>
 </book>

O elemento possui um <null/>elemento filho (de TStamper abaixo):

 <book>
     <title>Beowulf</title>
     <author><null/></author>
 </book>

Existe uma maneira correta ou canônica de representar esse nullvalor? Existem outras maneiras além dos exemplos acima?

O XML para os exemplos acima é artificial, portanto, não leia demais. :)

Rob Hruska
fonte

Respostas:

121

xsi: nil é a maneira correta de representar um valor tal que: Quando a chamada getElementValue () de nível 2 do DOM é emitida, o valor NULL é retornado. O xsi: nil também é usado para indicar um elemento válido sem conteúdo, mesmo que esse tipo de conteúdo normalmente não permita elementos vazios.

Se uma tag vazia for usada, getElementValue () retornará a string vazia ("") Se a tag for omitida, nenhuma tag de autor estará presente. Isso pode ser semanticamente diferente de defini-lo como 'nil' (por exemplo, definir "Série" como nulo pode ser que o livro não pertença a nenhuma série, embora omitir séries possa significar que a série é um elemento inaplicável ao elemento atual).

De: O W3C

Esquema XML: Estruturas introduz um mecanismo para sinalizar que um elemento deve ser aceito como · válido · quando não tiver conteúdo, apesar de um tipo de conteúdo que não requer ou nem necessariamente permite conteúdo vazio. Um elemento pode ser · válido · sem conteúdo se tiver o atributo xsi: nil com o valor true. Um elemento rotulado deve estar vazio, mas pode transportar atributos se permitido pelo tipo complexo correspondente.

Um esclarecimento:
Se você possui um elemento xml book e um dos elementos filhos é book: series, você tem várias opções ao preenchê-lo:

  1. Removendo o elemento completamente - Isso pode ser feito quando você deseja indicar que a série não se aplica a este livro ou se esse livro não faz parte de uma série. Nesse caso, transformações xsl (ou outros processadores baseados em eventos) que possuem um modelo que corresponde a book: series nunca serão chamados. Por exemplo, se o seu xsl transformar o elemento do livro na linha da tabela (xhtml: tr), você poderá obter o número incorreto de células da tabela (xhtml: td) usando este método.
  2. Deixando o elemento vazio - Isso pode indicar que a série é "" ou é desconhecida ou que o livro não faz parte de uma série. Qualquer transformação xsl (ou outro analisador baseado em evernt) que corresponda a book: series será chamada. O valor de current () será "". Você obterá o mesmo número de tags xhtml: td usando esse método como no próximo descrito.
  3. Usando xsi: nil = "true" - Isso significa que o elemento book: series é NULL, não apenas vazio. Sua transformação xsl (ou outro analisador baseado em evento) que tenha um livro de correspondência de modelo: series será chamada. O valor de current () estará vazio (string não vazia). A principal diferença entre esse método e (2) é que o tipo de esquema do livro: series não precisa permitir a sequência vazia ("") como um valor válido. Isso não faz sentido para um elemento de série, mas para um elemento de linguagem que é definido como um tipo enumerado no esquema, xsi: nil = "true" permite que o elemento não tenha dados. Outro exemplo seria elementos do tipo decimal. Se você deseja que eles estejam vazios, você pode unir uma seqüência de caracteres enumerada que permita apenas "" e um decimal, ou use um decimal que seja nillable.
KitsuneYMG
fonte
11
O uso do xsi: nil está correto, mas você deve garantir que ele esteja dentro do namespace apropriado: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
Na verdade é xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Observe o http: // ausente. É importante porque a string do namespace é na verdade apenas uma string para o analisador xml e não uma uri.
Burak Arslan
9
Acho que ainda está um pouco errado. Deveria ser xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Observe "www". Veja w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila
Como afirmado na minha resposta discordo da interpretação, uma vez que não é uma representação do estado do elemento, mas um constrangimento sobre o uso do elemento
Oakcool
2
@ ChrisV: Não é verdade, o xsi:prefixo deve ser declarado. Um analisador XML com reconhecimento de espaço de nome rejeitará seu documento XML se você tentar usar o xsi:prefixo sem declará-lo. A especificação relevante aqui é w3.org/TR/xml-names/#nsc-NSDeclared ("restrição de espaço para nome: prefixo declarado"), que diz que os únicos prefixos predefinidos são xml:e xmlns:. O Esquema XML baseia-se na especificação dos espaços para nome XML, mas não adiciona nenhum prefixo predefinido adicional, pois isso violaria a especificação dos espaços para nome XML.
Simon Kissane
9

Não há resposta canônica, pois o XML basicamente não tem conceito nulo. Mas suponho que você queira mapear Xml / Object (já que os gráficos de objetos têm nulos); então a resposta para você é "qualquer que seja a ferramenta usada". Se você escreve manipulação, isso significa o que você preferir. Para ferramentas que usam o Esquema XML, esse xsi:nilé o caminho a seguir. Para a maioria dos mapeadores, omitir elemento / atributo correspondente é a maneira de fazê-lo.

StaxMan
fonte
8

Depende de como você valida seu XML. Se você usar a validação do Esquema XML, a maneira correta de representar nullvalores é com o xsi:nilatributo

[ Fonte ]

Tormod Fjeldskår
fonte
7

A documentação no link w3

http://www.w3.org/TR/REC-xml/#sec-starttags

diz que estas são as formas recomendadas.

<test></test>
<test/>

O atributo mencionado na outra resposta é um mecanismo de validação e não uma representação do estado. Consulte o http://www.w3.org/TR/xmlschema-1/#xsi_nil

Esquema XML: Estruturas introduz um mecanismo para sinalizar que um elemento deve ser aceito como · válido · quando não tiver conteúdo, apesar de um tipo de conteúdo que não requer ou nem necessariamente permite conteúdo vazio. Um elemento pode ser · válido · sem conteúdo se tiver o atributo xsi: nil com o valor true. Um elemento assim rotulado deve estar vazio , mas pode carregar atributos se permitido pelo tipo complexo correspondente.

Para esclarecer esta resposta: Conteúdo

  <Book>
    <!--Invalid construct since the element attribute xsi:nil="true" signal that the element must be empty-->
    <BuildAttributes HardCover="true" Glued="true" xsi:nil="true">
      <anotherAttribute name="Color">Blue</anotherAttribute>
    </BuildAttributes>
    <Index></Index>
    <pages>
      <page pageNumber="1">Content</page>            
    </pages>
    <!--Missing ISBN number could be confusing and misguiding since its not present-->
  </Book>
</Books>
Oakcool
fonte
7
Essa é a recomendação para elementos vazios ; você é de opinião que vazio === nulo? Eu acredito que há uma diferença entre os dois, embora seja frequentemente situacional. Se você está afirmando que são iguais, recomendo mencionar esse argumento na sua resposta.
Rob Hruska
1
Vazio não é o mesmo que nulo; se fosse, essa pergunta sobre stackoverflow nunca teria sido feita. Esta resposta está errada. No entanto, o programador deve determinar se a lógica que estará lendo o xml está preparada para manipular um elemento ausente ou xsi: nil; caso contrário, pode ser necessário usar um desses formulários; isto é, pode ser necessário perder a distinção entre elemento nulo / ausente e um elemento vazio.
Home
@RobHruska sim, você está certo, é a definição de um elemento vazio, mas se levar em consideração a definição W3C apontada por KitsuneYMG, define que o elemento deve ser nulo e acredito que essa representação é mais uma definição do tag, em seguida, a representação de seu estado atual, então eu discordo dessa resposta e acredito que o vazio é a melhor representação de um elemento nulo. A ideia é simples: para manter uma boa estrutura, é necessário que todos os elementos sejam representados, caso contrário você não saberia de sua existência e, portanto, poderia deturpá-la.
Oakcool
4

Você usa xsi:nilquando a semântica do esquema indica que um elemento tem um valor padrão e que o valor padrão deve ser usado se o elemento não estiver presente. Eu tenho que assumir que existem pessoas inteligentes para quem a frase anterior não é uma idéia evidentemente terrível, mas parece nove tipos de coisas ruins para mim. Todo formato XML com o qual trabalhei representa valores nulos, omitindo o elemento. (Ou atributo, e boa sorte marcando um atributo com xsi:nil.)

Robert Rossney
fonte
Se em um aplicativo de publicação de documento você deseja que a data na página de título seja padronizada como a data atual, se o elemento não tiver conteúdo, omitir o dateelemento completamente não é de grande ajuda, pois o aplicativo não faz ideia de onde na página de título deseja a data para aparecer. (Se o elemento omitido tem apenas uma possível localização, este não é um problema, em vocabulários documentos reais quase todos os elementos têm muitas posições possíveis.)
CM Sperberg-McQueen
4

Simplesmente omitir o atributo ou elemento funciona bem em dados menos formais.

Se você precisar de informações mais sofisticadas, os esquemas GML adicionam o atributo nilReason, por exemplo: no GeoSciML :

  • xsi:nil com um valor "true" é usado para indicar que nenhum valor está disponível
  • nilReasonpode ser usado para registrar informações adicionais para valores ausentes; esse pode ser um dos motivos padrão da GML ( missing, inapplicable, withheld, unknown) ou o texto anexado por other:, ou pode ser um link de URI para uma explicação mais detalhada.

Quando você está trocando dados, a função para a qual o XML é comumente usado, os dados enviados para um destinatário ou para uma determinada finalidade pode ter um conteúdo oculto que estaria disponível para outra pessoa que pagasse ou tivesse autenticação diferente. Saber o motivo pelo qual o conteúdo estava faltando pode ser muito importante.

Os cientistas também estão preocupados com a falta de informações. Por exemplo, se ele foi descartado por motivos de qualidade, eles podem querer ver os dados incorretos originais.

Andy Dent
fonte
2

Em muitos casos, o objetivo de um valor Nulo é servir para um valor de dados que não estava presente em uma versão anterior do seu aplicativo.

Digamos que você tenha um arquivo xml do seu aplicativo "ReportMaster" versão 1.

Agora, no ReportMaster versão 2, foram adicionados mais alguns atributos que podem ou não ser definidos.

Se você usar a representação 'no tag significa null', obterá compatibilidade retroativa automática para ler seu arquivo xml ReportMaster 1.

Jeroen Dirks
fonte