¿Cuál es la forma correcta de representar elementos XML nulos?

166

He visto nullelementos representados de varias maneras:

El elemento está presente con xsi:nil="true":

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

El elemento está presente, pero se representa como un elemento vacío (que creo que está mal ya que está 'vacío' y nulles semánticamente diferente):

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

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

El elemento no está presente en absoluto en el marcado devuelto :

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

El elemento tiene un <null/>elemento hijo (de TStamper a continuación):

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

¿Existe una forma correcta o canónica de representar tal null valor? ¿Hay formas adicionales que los ejemplos anteriores?

El XML para los ejemplos anteriores está ideado, así que no lo leas demasiado. :)

Rob Hruska
fuente

Respuestas:

121

xsi: nil es la forma correcta de representar un valor tal que: cuando se emite la llamada DOM Nivel 2 getElementValue (), se devuelve el valor NULL. xsi: nil también se usa para indicar un elemento válido sin contenido, incluso si ese tipo de contenido de elementos normalmente no permite elementos vacíos.

Si se usa una etiqueta vacía, getElementValue () devuelve la cadena vacía ("") Si se omite la etiqueta, entonces ni siquiera hay una etiqueta de autor. Esto puede ser semánticamente diferente de establecerlo en 'nulo' (Ej. Establecer "Serie" en nulo puede ser que el libro no pertenezca a ninguna serie, mientras que omitir series podría significar que la serie es un elemento inaplicable al elemento actual).

De: El W3C

Esquema XML: Structures introduce un mecanismo para indicar que un elemento debe ser aceptado como · válido · cuando no tiene contenido a pesar de un tipo de contenido que no requiere o incluso necesariamente permite contenido vacío. Un elemento puede ser · válido · sin contenido si tiene el atributo xsi: nil con el valor verdadero. Un elemento así etiquetado debe estar vacío, pero puede llevar atributos si lo permite el tipo complejo correspondiente.

Una aclaración:
si tiene un elemento xml de libro y uno de los elementos secundarios es book: series, tiene varias opciones al completarlo:

  1. Eliminar completamente el elemento: esto se puede hacer cuando desee indicar que la serie no se aplica a este libro o que ese libro no forma parte de una serie. En este caso, las transformaciones xsl (u otros procesadores basados ​​en eventos) que tengan una plantilla que coincida con book: series nunca serán llamadas. Por ejemplo, si su xsl convierte el elemento del libro en una fila de la tabla (xhtml: tr), puede obtener el número incorrecto de celdas de la tabla (xhtml: td) utilizando este método.
  2. Dejar el elemento vacío: esto podría indicar que la serie es "", o es desconocida, o que el libro no es parte de una serie. Se llamará a cualquier transformación xsl (u otro analizador basado en Evernt) que coincida con book: series. El valor de current () será "". Obtendrá el mismo número de etiquetas xhtml: td usando este método que con el siguiente descrito.
  3. Usando xsi: nil = "true" - Esto significa que el elemento book: series es NULL, no solo vacío. Se llamará a su transformación xsl (u otro analizador basado en eventos) que tenga un libro de coincidencia de plantillas: series. El valor de current () estará vacío (no cadena vacía). La principal diferencia entre este método y (2) es que el tipo de esquema de book: series no necesita permitir que la cadena vacía ("") sea un valor válido. Esto no tiene ningún sentido real para un elemento de serie, pero para un elemento de lenguaje que se define como un tipo enumerado en el esquema, xsi: nil = "true" permite que el elemento no tenga datos. Otro ejemplo serían elementos de tipo decimal. Si desea que estén vacías, puede unir una cadena enumerada que solo permita "" y un decimal, o usar un decimal que sea numerable.
KitsuneYMG
fuente
11
Usar xsi: nil es correcto, pero debe asegurarse de que esté dentro del espacio de nombres adecuado: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
En realidad es xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Tenga en cuenta la falta http: //. Es importante porque la cadena de espacio de nombres es en realidad solo una cadena para el analizador xml y no una uri.
Burak Arslan
9
Je, creo que todavía está un poco mal. Debería ser xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Nota "www". Ver w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila
Como se indicó en mi respuesta, no estoy de acuerdo con la interpretación, ya que no es una representación del estado del elemento, sino una restricción en el uso del elemento
Oakcool
2
@ChrisV: No es cierto, el xsi:prefijo debe declararse. Un analizador XML compatible con el espacio de nombres rechazará su documento XML si intenta usar el xsi:prefijo sin declararlo. La especificación relevante aquí es w3.org/TR/xml-names/#nsc-NSDeclared ("Restricción de espacio de nombres: Prefijo declarado") que dice que los únicos prefijos predefinidos son xml:y xmlns:. El esquema XML se basa en la especificación de los espacios de nombres XML, pero no agrega ningún prefijo predefinido adicional, ya que esto violaría la especificación de los espacios de nombres XML.
Simon Kissane
9

No hay una respuesta canónica, ya que XML fundamentalmente no tiene un concepto nulo. Pero supongo que desea mapeo Xml / Object (ya que los gráficos de objetos tienen valores nulos); entonces la respuesta para usted es "cualquier cosa que use su herramienta". Si escribe manejo, eso significa lo que prefiera. Para las herramientas que usan el esquema XML, este xsi:niles el camino a seguir. Para la mayoría de los mapeadores, omitir el elemento / atributo coincidente es la forma de hacerlo.

StaxMan
fuente
8

Depende de cómo valides tu XML. Si utiliza la validación del esquema XML, la forma correcta de representar los nullvalores es con elxsi:nil atributo

[ Fuente ]

Tormod Fjeldskår
fuente
7

La documentación en el enlace w3

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

dice que estas son las formas recomendadas.

<test></test>
<test/>

El atributo mencionado en la otra respuesta es el mecanismo de validación y no una representación del estado. Consulte el http://www.w3.org/TR/xmlschema-1/#xsi_nil

Esquema XML: Structures introduce un mecanismo para indicar que un elemento debe ser aceptado como · válido · cuando no tiene contenido a pesar de un tipo de contenido que no requiere o incluso necesariamente permite contenido vacío. Un elemento puede ser · válido · sin contenido si tiene el atributo xsi: nil con el valor verdadero. Un elemento así etiquetado debe estar vacío , pero puede llevar atributos si lo permite el tipo complejo correspondiente.

Para aclarar esta respuesta: Contenido

  <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
fuente
77
Esa es la recomendación para elementos vacíos ; ¿Eres de la opinión de que vacío === nulo? Creo que hay una diferencia entre los dos, aunque a menudo es situacional. Si está haciendo la afirmación de que son iguales, le recomiendo mencionar ese argumento en su respuesta.
Rob Hruska
1
Vacío no es lo mismo que nulo; si lo fuera, esta pregunta de stackoverflow nunca se hubiera hecho. Esta respuesta es incorrecta. Sin embargo, el programador debe determinar si la lógica que leerá el xml está preparada para manejar un elemento faltante o xsi: nil; de lo contrario, podría ser necesario usar uno de estos formularios; es decir, puede ser necesario perder la distinción entre elemento nulo / faltante y un elemento vacío.
ToolmakerSteve
@RobHruska sí, tiene razón, es la definición de un elemento vacío, pero si considera la definición W3C que señaló KitsuneYMG, define que el elemento debe ser nulo y creo que esa representación es más una definición de etiqueto entonces la representación de su estado actual, por lo que no estoy de acuerdo con esa respuesta, y creo que el vacío es la mejor representación de un elemento nulo. La idea es simple, para mantener una buena estructura, necesita que todos los elementos estén representados, de lo contrario no sabría de su existencia y, por lo tanto, podría tergiversarlo.
Oakcool
4

Se usa xsi:nilcuando la semántica de su esquema indica que un elemento tiene un valor predeterminado y que el valor predeterminado debe usarse si el elemento no está presente. Tengo que suponer que hay personas inteligentes para quienes la oración anterior no es una idea evidentemente terrible, pero me parece nueve tipos de cosas malas. Todos los formatos XML con los que he trabajado representan valores nulos al omitir el elemento. (O atributo, y buena suerte marcando un atributo con xsi:nil).

Robert Rossney
fuente
Si en una aplicación de publicación de documentos desea que la fecha en la página de título sea predeterminada a la fecha actual si el elemento no tiene contenido, omitir el dateelemento por completo no es de mucha ayuda, ya que la aplicación no tendrá idea de en qué parte de la página de título desea La fecha para aparecer. (Si el elemento omitido tiene solo una ubicación posible, esto no es un problema; en vocabularios de documentos reales, casi todos los elementos tienen muchas ubicaciones posibles.)
CM Sperberg-McQueen
4

Simplemente omitir el atributo o elemento funciona bien en datos menos formales.

Si necesita información más sofisticada, los esquemas GML agregan el atributo nilReason, por ejemplo: en GeoSciML :

  • xsi:nil con un valor de "verdadero" se utiliza para indicar que no hay ningún valor disponible
  • nilReasonpuede usarse para registrar información adicional para valores perdidos; Este puede ser uno de los motivos estándar de GML ( missing, inapplicable, withheld, unknown), o texto precedido por other:, o puede ser un enlace de URI a una explicación más detallada.

Cuando intercambia datos, la función para la que se usa comúnmente XML, los datos enviados a un destinatario o para un propósito determinado pueden tener contenido oculto que estaría disponible para otra persona que pagó o tuvo una autenticación diferente. Saber la razón por la que faltaba contenido puede ser muy importante.

A los científicos también les preocupa por qué falta información. Por ejemplo, si se descartó por razones de calidad, es posible que deseen ver los datos incorrectos originales.

Andy Dent
fuente
2

En muchos casos, el propósito de un valor nulo es servir para un valor de datos que no estaba presente en una versión anterior de su aplicación.

Supongamos que tiene un archivo xml de su aplicación "ReportMaster" versión 1.

Ahora, en ReportMaster versión 2, se han agregado algunos atributos más que pueden o no estar definidos.

Si utiliza la representación 'sin etiqueta significa nulo', obtendrá compatibilidad automática con versiones anteriores para leer su archivo xml de ReportMaster 1.

Jeroen Dirks
fuente