¿Qué hace elementFormDefault en XSD?


88

¿Qué hace elementFormDefaulty cuándo debe usarse?

Entonces encontré algunas definiciones de elementFormDefaultvalores:

calificado : los elementos y atributos están en el targetNamespace del esquema

no calificado : los elementos y atributos no tienen un espacio de nombres

Entonces, a partir de esa definición, pensaría que si un esquema está configurado como calificado, ¿por qué debe prefijar el tipo con el espacio de nombres? ¿Y cuáles son los escenarios en los que incluso tendrías uno configurado como no calificado para el caso? Intenté buscar en Google, pero todo lo que obtuve fueron un par de páginas del W3C que eran extremadamente difíciles de entender.

Este es el archivo con el que estoy trabajando en este momento, ¿por qué necesito declarar el tipo como target:TypeAssignmentscuando declaro que targetNamespacees el mismo que xmlns:target?

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns" 
        elementFormDefault="qualified">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignments" type="target:TypeAssignments"
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="TypeAssignments">
    <sequence>
      <element name="assignment" type="target:assignmentInfo"
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
      <element name="page" type="target:TypePage"/>
      <element name="file" type="target:TypeFile" 
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
  <simpleType name="TypePage">
    <restriction base="integer">
      <minInclusive value="50" />
      <maxInclusive value="498" />
    </restriction>
  </simpleType>
  <simpleType name="TypeFile">
    <restriction base="string">
      <enumeration value=".xml" />
      <enumeration value=".dtd" />
      <enumeration value=".xsd" />
    </restriction>
  </simpleType>
</schema>

Respuestas:


71

ElementFormDefault no tiene nada que ver con el espacio de nombres de los tipos en el esquema, se trata de los espacios de nombres de los elementos en los documentos XML que cumplen con el esquema.

Aquí está la sección relevante de la especificación:

Element Declaration Schema

Component Property  {target namespace}
Representation      If form is present and its ·actual value· is qualified, 
                    or if form is absent and the ·actual value· of 
                    elementFormDefault on the <schema> ancestor is qualified, 
                    then the ·actual value· of the targetNamespace [attribute]
                    of the parent <schema> element information item, or 
                    ·absent· if there is none, otherwise ·absent·.

Lo que eso significa es que el targetNamespace que ha declarado en la parte superior del esquema solo se aplica a los elementos del documento XML compatible con el esquema si elementFormDefault está "calificado" o si el elemento se declara explícitamente en el esquema con form = "calificado" .

Por ejemplo: si elementFormDefault no está calificado -

<element name="name" type="string" form="qualified"></element>
<element name="page" type="target:TypePage"></element>

esperará que los elementos "name" estén en el targetNamespace y los elementos "page" estén en el espacio de nombres nulo.

Para evitar tener que poner form = "calificado" en cada declaración de elemento, indicar elementFormDefault = "calificado" significa que targetNamespace se aplica a cada elemento a menos que se anule poniendo form = "unqualified" en la declaración del elemento.


Aunque esta respuesta se refiere a la especificación, no la interpreta correctamente. Los elementos definidos localmente todavía están en targetNamespace y nunca están en el espacio de nombres nulo. elementFormDefault es solo un conmutador que especifica si se supone que debe calificarlos con el espacio de nombres en una instancia.
Ihe Onwuka

1
@ Je, eso no es correcto: o en todo caso, puede confundir a la gente. Si una declaración de elemento local no tiene form = calificado, entonces la propiedad {target namespace} del componente del esquema de declaración del elemento está "ausente", y eso significa que la propiedad URI del espacio de nombres de la instancia del elemento también debe estar "ausente".
Michael Kay

@MichaelKay Para mí eso es aún más confuso. La pregunta es si en la página de ejemplo está en el espacio de nombres nulo, porque si es así, la especificación simplemente no dice que la configuración elementFormDefault = unqualified coloca elementos definidos localmente en el espacio de nombres nulo. Está diciendo que la página no debe estar calificada por espacio de nombres en una instancia, lo mismo que decir que la página no está en un espacio de nombres porque si es por eso que la especificación simplemente no dice eso y por qué un esquema con un targetNamespace valida cosas que no lo son en ese espacio de nombres?
Ihe Onwuka

1
No "simplemente dice eso" porque lo está describiendo de manera muy informal: la frase "poner un elemento en el espacio de nombres nulo" no usa la terminología de la especificación XSD; la especificación prefiere usar una terminología mucho más cuidadosa, lo que a menudo dificulta la lectura pero termina siendo mucho más precisa.
Michael Kay

1
En lo que a mí respecta, es una respuesta correcta tal como está escrita.
Michael Kay

60

Considere el siguiente ComplexType AuthorTypeusado por authorelemento

<xsd:complexType name="AuthorType">
  <!-- compositor goes here -->
  <xsd:sequence>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="phone" type="tns:Phone"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="tns:AuthorId"/>
</xsd:complexType>
<xsd:element name="author" type="tns:AuthorType"/>

Si elementFormDefault="unqualified"

entonces la siguiente instancia XML es válida

<x:author xmlns:x="http://example.org/publishing">
   <name>Aaron Skonnard</name>
   <phone>(801)390-4552</phone>
</x:author>

el atributo de nombre de los autores está permitido sin especificar el espacio de nombres (no calificado). Los elementos que forman parte de <xsd:complexType>se consideran locales de complexType.

Si elementFormDefault="qualified"

entonces la instancia debe tener los elementos locales calificados

<x:author xmlns:x="http://example.org/publishing">
   <x:name>Aaron Skonnard</name>
   <x:phone>(801)390-4552</phone>
</x:author>

Consulte este enlace para obtener más detalles.


55

Respuesta y explicación nuevas y detalladas a una pregunta antigua y frecuente ...

Respuesta corta : Si no se agrega elementFormDefault="qualified"a xsd:schema, el valor por defecto unqualifiedvalor significa que los elementos declarados localmente están en ningún espacio de nombres .

Hay mucha confusión con respecto a lo que elementFormDefaulthace, pero esto se puede aclarar rápidamente con un breve ejemplo ...

Versión optimizada de su XSD:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignment" type="target:assignmentInfo" 
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
</schema>

Puntos clave:

  • El assignmentelemento está definido localmente.
  • Los elementos definidos localmente en XSD no están en ningún espacio de nombres de forma predeterminada.
    • Esto se debe a que el valor predeterminado de elementFormDefaultes unqualified.
    • Podría decirse que esto es un error de diseño de los creadores de XSD.
    • La práctica estándar es utilizar siempre de elementFormDefault="qualified" modo que assignmentesté en el espacio de nombres de destino como cabría esperar.
  • Es un formatributo de uso poco frecuente en xs:elementdeclaraciones para las que elementFormDefaultestablece valores predeterminados.

XML aparentemente válido

Este XML parece que debería ser válido de acuerdo con el XSD anterior:

<assignments xmlns="http://www.levijackson.net/web340/ns"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.levijackson.net/web340/ns try.xsd">
  <assignment id="a1">
    <name>John</name>
  </assignment>
</assignments>

Darse cuenta:

  • El espacio de nombres predeterminado en assignmentslugares assignmentsy todos sus descendientes en el espacio de nombres predeterminado ( http://www.levijackson.net/web340/ns).

Error de validación desconcertante

A pesar de parecer válido, el XML anterior produce el siguiente error de validación confuso:

[Error] try.xml: 4: 23: cvc-complex-type.2.4.a: Se encontró contenido no válido comenzando con el elemento 'asignación'. Se espera uno de '{asignación}'.

Notas:

  • No sería el primer desarrollador en maldecir este diagnóstico que parece decir que el contenido no es válido porque esperaba encontrar un assignmentelemento, pero en realidad encontró un assignmentelemento. ( WTF )
  • Lo que esto realmente significa: el {y }alrededor assignmentsignifica que la validación no se esperaba assignment en ningún espacio de nombres aquí. Desafortunadamente, cuando dice que encontró un assignmentelemento, no menciona que lo encontró en un espacio de nombres predeterminado que difiere de ningún espacio de nombres.

Solución

  • La gran mayoría de las veces: agregue elementFormDefault="qualified"al xsd:schemaelemento del XSD. Esto significa que XML válido debe colocar elementos en el espacio de nombres de destino cuando se declara localmente en el XSD; de lo contrario, XML válido debe colocar elementos declarados localmente en ningún espacio de nombres.
  • Una pequeña minoría de las veces: cambie el XML para cumplir con el requisito de XSD de que assignmentno haya espacio de nombres. Esto se puede lograr, por ejemplo, agregando xmlns=""al assignmentelemento.

Créditos: Gracias a Michael Kay por sus útiles comentarios sobre esta respuesta.


12

Es importante tener en cuenta que elementFormDefault es que se aplica a elementos definidos localmente , normalmente elementos con nombre dentro de un bloque complexType, a diferencia de los elementos globales definidos en el nivel superior del esquema. Con elementFormDefault = "calificado" puede abordar elementos locales en el esquema desde dentro del documento xml utilizando el espacio de nombres de destino del esquema como el espacio de nombres predeterminado del documento.

En la práctica, use elementFormDefault = "qualified" para poder declarar elementos en bloques anidados; de lo contrario, tendrá que declarar todos los elementos en el nivel superior y hacer referencia a ellos en el esquema en elementos anidados utilizando el atributo ref, lo que da como resultado un esquema mucho menos compacto.

Este bit en XML Schema Primer habla de ello: http://www.w3.org/TR/xmlschema-0/#NS


Ligera aclaración sobre lo que parece ser la respuesta más precisa. Con elementFormDefault = calificado, debe calificar los elementos locales del espacio de nombres en la entrada. Si se establece en no calificado, no debe calificarlos con un espacio de nombres.
Ihe Onwuka

6

elementFormDefault = "calificado" se utiliza para controlar el uso de espacios de nombres en documentos de instancia XML (archivo .xml), en lugar de espacios de nombres en el documento de esquema en sí (archivo .xsd).

Al especificar elementFormDefault = "calificado", aplicamos la declaración de espacio de nombres para que se utilice en documentos validados con este esquema.

Es una práctica común especificar este valor para declarar que los elementos deben estar calificados en lugar de no calificados. Sin embargo, dado que attributeFormDefault = "unqualified" es el valor predeterminado, no es necesario especificarlo en el documento de esquema, si no se desea calificar los espacios de nombres.


elementFormDefault solo se aplica a elementos definidos localmente. Los elementos globales deben estar calificados por espacios de nombres independientemente.
Ihe Onwuka

0

He notado que XMLSpy (al menos la versión 2011) necesita un targetNameSpace definido si se usa elementFormDefault = "calificado". De lo contrario, no se validará. Y tampoco generará xmls con prefijos de espacio de nombres

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.