sirve - ¿Un espacio de nombres xml es igual a un solo archivo de esquema?
qué es un archivo xml y para qué sirve (1)
... o ¿Por qué estos archivos se validan en Visual Studio 2010 pero no con xmllint 1 ?
Actualmente estoy trabajando contra un esquema xml publicado donde el hábito del autor original es dividir los esquemas en varios archivos .xsd, pero donde algunos archivos de esquema tienen el mismo targetNamespace
. ¿Es esto realmente "permitido"?
Ejemplo (extremadamente simplificado):
File targetNamespace Contents
------------------------------------------------------------
b1.xsd uri:tempuri.org:b complex type "fooType"
b2.xsd uri:tempuri.org:b simple type "barType"
a.xsd uri:tempuri.org:a imports b1.xsd and b2.xsd
definition of root element "foo", that
extends "b:fooType" with an attribute
of "b:barType"
(Complete el contenido del archivo a continuación).
Luego tengo un archivo xml, data.xml
, con este contenido:
<?xml version="1.0"?>
<foo bar="1" xmlns="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" />
Durante mucho tiempo, he creído que todo esto era correcto, ya que Visual Studio aparentemente permite este estilo de esquema. Sin embargo, hoy decidí configurar una utilidad de línea de comandos para validar archivos xml y elegí xmllint
.
Cuando ejecuté xmllint --schema a.xsd data.xml
, se me presentó esta advertencia:
a.xsd: 4: elemento import: Schemas parser warning: Elemento ''{ http://www.w3.org/2001/XMLSchema } import'': omitiendo la importación del esquema ubicado en ''b2.xsd'' para el espacio de nombres ''uri: tempuri.org:b '', ya que este espacio de nombres ya se importó con el esquema ubicado en'' b1.xsd ''.
El hecho de que se haya omitido la importación de b2.xsd
obviamente conduce a este error:
a.xsd: 9: atributo del elemento: Error del analizador de esquemas: atributo decl. ''barra'', atributo ''tipo'': el valor QName ''{uri: tempuri.org: b} barType'' no se resuelve con una (n) definición de tipo simple.
Si xmllint
es correcto, habría un error en las especificaciones publicadas con las que estoy trabajando. ¿Esta ahí? Y Visual Studio estaría mal. ¿Lo es?
Me doy cuenta de la diferencia entre xs:import
y xs:include
. En este momento, simplemente no veo cómo xs:include
podría arreglar las cosas, ya que:
-
b1.xsd
yb2.xsd
tienen el mismotargetNamespace
- ambos difieren en
targetNamespace
dea.xsd
- y ellos no (necesitan) saber el uno del otro
¿Es este un defecto en la especificación del esquema original? Estoy empezando a pensar que el tercer punto es crucial. ¿Para empezar, el hecho de que no se conozcan entre sí ha llevado a colocarlos en diferentes espacios de nombres?
b1.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="fooType" />
</xs:schema>
b2.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="barType">
<xs:restriction base="xs:integer" />
</xs:simpleType>
</xs:schema>
a.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:b="uri:tempuri.org:b">
<xs:import namespace="uri:tempuri.org:b" schemaLocation="b1.xsd" />
<xs:import namespace="uri:tempuri.org:b" schemaLocation="b2.xsd" />
<xs:element name="foo">
<xs:complexType>
<xs:complexContent>
<xs:extension base="b:fooType">
<xs:attribute name="bar" type="b:barType" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
Notas:
1) Estoy usando el puerto de libxml2/xmllint encuentra en www.zlatkovic.com .
El quid del problema aquí es qué significa cuando tiene dos elementos <import>
diferentes, cuando ambos se refieren al mismo espacio de nombres.
Es schemaLocation
aclarar el significado cuando considera que el atributo schemaLocation
de <import>
es completamente opcional. Cuando lo dejas afuera, solo estás diciendo "Quiero importar el esquema del espacio de nombres XYZ a este esquema". schemaLocation
es solo una sugerencia de dónde encontrar la definición de ese otro esquema.
El significado preciso de <import>
es un poco borroso cuando lees la especificación W3C, posiblemente de forma deliberada. Como resultado, las interpretaciones varían.
Algunos procesadores XML toleran múltiples <import>
para el mismo espacio de nombres, y esencialmente amalgaman todo el schemaLocation
en un solo destino.
Otros procesadores son más estrictos y deciden que solo un <import>
por espacio de nombres de destino es válido. Creo que esto es más correcto, cuando consideras que schemaLocation
es opcional.
Además de los ejemplos de VS y xmllint que proporcionó, Xerces-J también es muy estricto, e ignora el <import>
posterior para el mismo espacio de nombres de destino, dando el mismo error que hace xmllint. XML Spy, por otro lado, es mucho más permisivo (pero luego, la validación de XML Spy es notoriamente inestable)
Para estar seguro, no debe tener estas múltiples importaciones. Un espacio de nombres dado debe tener un solo documento "maestro", que a su vez tiene un <include>
para cada sub-documento. Este maestro es a menudo altamente artificial, actuando solo como un contenedor. para estos sub-documentos.
Por lo que he visto, esto generalmente consiste en la "mejor práctica" para el esquema XML cuando se trata de la máxima compatibilidad de la herramienta, pero algunos argumentarán que es un truco que aleja el diseño elegante del esquema.
Meh