understanding - xml with schema
¿Qué hace elementFormDefault en XSD? (6)
¿Qué hace elementFormDefault
y cuándo se debe usar?
Así que encontré algunas definiciones para los valores de elementFormDefault
:
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, creo que si un esquema se configura como calificado, ¿por qué debe prefijar el tipo con el espacio de nombres? ¿Y cuáles son los escenarios que incluso tendrías uno sin calificar para ese asunto? Probé Google, pero todo lo que obtuve fueron un par de páginas 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:TypeAssignments
cuando declaro el targetNamespace
como 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>
Considere el siguiente AuthorType
de author
AuthorType
utilizado por el elemento author
<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"
luego, 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 del nombre del autor está permitido sin especificar el espacio de nombre (no calificado). Todos los elementos que son parte de <xsd:complexType>
se consideran locales a complexType.
if elementFormDefault="qualified"
entonces la instancia debería 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>
por favor, consulte this enlace para más detalles
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 en el documento XML compatible con el esquema si elementFormDefault está "calificado" o si el elemento se declara explícitamente en el esquema como form = "qualified" .
Por ejemplo: si elementFormDefault no está calificado,
<element name="name" type="string" form="qualified"></element>
<element name="page" type="target:TypePage"></element>
pondrá los elementos de "nombre" para que estén en el espacio de destino y los elementos de "página" estén en el espacio de nombres nulo.
Para ahorrarle tener que poner form = "calificado" en cada declaración de elemento, indicando elementFormDefault = "qualified" significa que el targetNamespace se aplica a cada elemento a menos que se anule poniendo form = "no calificado" en la declaración del elemento.
Es importante tener en cuenta que elementFormDefault es aplicable a los elementos definidos localmente , típicamente elementos nombrados dentro de un bloque complexType, en contraposición a los elementos globales definidos en el nivel superior del esquema. Con elementFormDefault = "qualified" puede abordar los elementos locales en el esquema desde el documento xml utilizando el espacio de nombres de destino del esquema como el espacio de nombre 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 referirse a ellos en el esquema en elementos anidados utilizando el atributo ref, lo que resulta en un mucho menos esquema compacto.
Este fragmento en el XML Schema Primer habla al respecto: http://www.w3.org/TR/xmlschema-0/#NS
Me di cuenta de que XMLSpy (al menos la versión 2011) necesita un targetNameSpace definido si se usa elementFormDefault = "qualified". De lo contrario no validará. Y tampoco generará xmls con prefijos de espacio de nombres
elementFormDefault = "qualified" se usa para controlar el uso de espacios de nombres en documentos de instancia XML (archivo .xml), en lugar de espacios de nombres en el propio documento de esquema (archivo .xsd).
Al especificar elementFormDefault = "qualified" aplicamos la declaración de espacio de nombres para ser utilizada en documentos validados con este esquema.
Es una práctica común especificar este valor para declarar que los elementos deben ser calificados en lugar de no calificados. Sin embargo, dado que attributeFormDefault = "no calificado" es el valor predeterminado, no es necesario especificarlo en el documento de esquema, si no se quiere calificar los espacios de nombres.
Respuesta y explicación nuevas y detalladas a una vieja pregunta frecuente ...
Respuesta corta : si no agrega elementFormDefault="qualified"
a xsd:schema
, entonces el valor predeterminado unqualified
significa que los elementos declarados localmente no están en ningún espacio de nombres .
Hay mucha confusión con respecto a lo que hace elementFormDefault
, 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 elemento de
assignment
está definido localmente. - Los elementos definidos localmente en XSD no están en ningún espacio de nombres por defecto.
- Esto se debe a que el valor predeterminado para
elementFormDefault
unqualified
estáunqualified
. - Esto posiblemente sea un error de diseño de los creadores de XSD.
- La práctica estándar es usar siempre
elementFormDefault="qualified"
para que laassignment
esté en el espacio de nombres de destino como uno esperaría.
- Esto se debe a que el valor predeterminado para
XML aparentemente válido
Este XML parece que debe 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 nombre predeterminado en las
assignments
coloca lasassignments
y 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 ''{assignment}''.
Notas:
- No sería el primer desarrollador que maldice este diagnóstico que parece decir que el contenido no es válido porque esperaba encontrar un elemento de
assignment
pero en realidad encontró un elemento deassignment
. ( WTF ) - Lo que esto realmente significa: la
{
and}
assignment
alrededor significa que la validación estaba esperando laassignment
en ningún espacio de nombres aquí. Desafortunadamente, cuando dice que encontró un elemento deassignment
, no menciona que lo encontró en un espacio de nombre predeterminado que difiere de ningún espacio de nombres.
Solución
- La gran mayoría de las veces: agrega
elementFormDefault="qualified"
al elementoxsd:schema
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. - Minúscula minoría de las veces: cambie el XML para cumplir con el requisito del XSD de que la
assignment
esté en ningún espacio de nombres. Esto se puede lograr, por ejemplo, agregandoxmlns=""
al elemento deassignment
.