para pagina ltr lenguaje idioma español definir codigo cambiar xml performance xsd expat-parser

pagina - ¿Puedo imponer el orden de los atributos XML utilizando un esquema?



html lang es dir ltr (8)

Como han señalado otros, no, no puede confiar en el orden de los atributos.

Si tuviera algún proceso que involucrase 2,500 archivos XML y 1,5 millones de pares clave / valor, obtendría esos datos fuera de XML y los pondré en una forma más utilizable tan pronto como sea posible. Una base de datos, un formato de serialización binario, lo que sea. No está obteniendo ninguna ventaja de usar XML (aparte de la validación de esquemas). Actualizaba mi tienda cada vez que obtenía un nuevo archivo XML y eliminaba 1.5 millones de elementos XML del flujo principal de mi proceso.

Nuestra aplicación C ++ lee datos de configuración de archivos XML que se parecen a esto:

<data> <value id="FOO1" name="foo1" size="10" description="the foo" ... /> <value id="FOO2" name="foo2" size="10" description="the other foo" ... /> ... <value id="FOO300" name="foo300" size="10" description="the last foo" ... /> </data>

La configuración completa de la aplicación consiste en ~ 2500 de estos archivos XML (que se traducen en más de 1.5 millones de pares de atributos clave / valor). Los archivos XML provienen de muchas fuentes / equipos diferentes y se validan contra un esquema. Sin embargo, a veces los nodos <value/> ven así:

<value name="bar1" id="BAR1" description="the bar" size="20" ... />

o esto:

<value id="BAT1" description="the bat" name="bat1" size="25" ... />

Para que este proceso sea rápido, estamos utilizando Expat para analizar los documentos XML. Expat expone los atributos como una matriz, como esto:

void ExpatParser::StartElement(const XML_Char* name, const XML_Char** atts) { // The attributes are stored in an array of XML_Char* where: // the nth element is the ''key'' // the n+1 element is the value // the final element is NULL for (int i = 0; atts[i]; i += 2) { std::string key = atts[i]; std::string value = atts[i + 1]; ProcessAttribute (key, value); } }

Esto pone toda la responsabilidad en nuestra función ProcessAttribute() para leer la "clave" y decidir qué hacer con el valor. La creación de perfiles de la aplicación ha demostrado que alrededor del 40% del tiempo total de análisis de XML se ocupa de estos atributos por nombre / cadena.

El proceso general podría acelerarse drásticamente si pudiera garantizar / imponer el orden de los atributos (para empezar, no hay comparaciones de cadenas en ProcessAttribute() ). Por ejemplo, si el atributo ''id'' siempre fue el 1er atributo, podríamos tratarlo directamente:

void ExpatParser::StartElement(const XML_Char* name, const XML_Char** atts) { // The attributes are stored in an array of XML_Char* where: // the nth element is the ''key'' // the n+1 element is the value // the final element is NULL ProcessID (atts[1]); ProcessName (atts[3]); //etc. }

De acuerdo con las especificaciones del esquema W3C, puedo usar <xs:sequence> en un esquema XML para imponer el orden de los elementos, pero parece que no funciona para los atributos, o quizás lo estoy usando incorrectamente:

<xs:element name="data"> <xs:complexType> <xs:sequence> <xs:element name="value" type="value_type" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="value_type"> <!-- This doesn''t work --> <xs:sequence> <xs:attribute name="id" type="xs:string" /> <xs:attribute name="name" type="xs:string" /> <xs:attribute name="description" type="xs:string" /> </xs:sequence> </xs:complexType>

¿Hay alguna forma de imponer el orden de los atributos en un documento XML? Si la respuesta es "no", ¿podría alguien sugerir una alternativa que no conlleve una gran penalización en el rendimiento en tiempo de ejecución?


Estoy bastante seguro de que no hay forma de imponer el orden de los atributos en un documento XML. Asumiré que puede insistir en ello a través de un proceso de negocios u otros factores humanos, como un contrato u otro documento.

¿Qué pasaría si asumiera que el primer atributo era "id" y probara el nombre para estar seguro? Si es así, use el valor, si no, puede intentar obtener el atributo por nombre o tirar el documento.

Si bien no es tan eficiente como invocar el atributo por su ordinal, algunas veces no podrán estimar que sus proveedores de datos han entregado XML a especificaciones. El resto del tiempo, puede tomar otra acción.


La respuesta es no, ay. Estoy sorprendido por tu cifra del 40%. Me resulta difícil creer que convertir "foo" en ProcessFoo demore tanto. ¿Está seguro de que el 40% no incluye el tiempo necesario para ejecutar ProcessFoo?

¿Es posible acceder a los atributos por nombre utilizando esta opción Expat? Esa es la forma más tradicional de acceder a los atributos. No estoy diciendo que vaya a ser más rápido, pero podría valer la pena intentarlo.


Los atributos XML no tienen una orden, por lo tanto, no hay una orden que cumplir.

Si quieres algo ordenado, necesitas elementos XML. O algo diferente de XML. JSON, YAML y bEncode, por ejemplo, tienen mapas (que no están ordenados) y secuencias (que están ordenadas).


No creo que el esquema XML lo admita (los atributos solo están definidos y restringidos por su nombre, por ejemplo, tienen que coincidir con un nombre en particular), pero no veo cómo podría definir un orden para esos atributos en XSD.

No conozco ninguna otra forma de asegurar que los atributos en un nodo XML vienen en un orden particular, no estoy seguro de si alguno de los otros mecanismos de esquema XML como Schematron o Relax NG admitiría eso ...


Por lo que recuerdo, Expat es un analizador que no valida y es mejor para él ... así que probablemente puedas desechar esa idea de XSD. El orden dependiente tampoco es una buena idea en muchos enfoques de XML (XSD fue criticado en el orden de los elementos una gran cantidad de tiempo atrás, por ejemplo, por parte de profesionales o antipendedores de XML Web Services en MSFT).

Realice su codificación personalizada y simplemente extienda su lógica para una búsqueda más eficiente o profundice en la fuente del analizador. Es trivial escribir el herramental alrededor de la codificación de reemplazo eficiente mientras se protege a los agentes de software y los usuarios de él ... lo que desea hacer para que se pueda migrar fácilmente al tiempo que se conserva la compatibilidad y reversibilidad. También, vaya por restricciones de tamaño fijo / traducción de nombre de atributo.

[Considérate afortunado con Expat :) y su velocidad bruta. Imagínese cómo a los desarrolladores de CLR les encantan las funciones de escalado XML, envían de forma rutinaria 200 MB en el cable en proceso de "solo consultar la base de datos" ..]


Según la especificación xml,

el orden de las especificaciones de atributos en una etiqueta de inicio o etiqueta de elemento vacío no es significativo

Puedes comprobarlo en la sección 3.1.


Solo una conjetura, ¿pero puede intentar agregar use="required" a cada una de sus especificaciones de atributos?

<xs:complexType name="value_type"> <!-- This doesn''t work --> <xs:sequence> <xs:attribute name="id" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="description" type="xs:string" use="required" /> </xs:sequence> </xs:complexType>

Me pregunto si el analizador se está ralentizando al permitir atributos opcionales, cuando aparezca, sus atributos siempre estarán allí.

Una vez más, sólo una conjetura.

EDIT: La especificación XML 1.0 dice que el orden de los atributos no es significativo. http://www.w3.org/TR/REC-xml/#sec-starttags

Por lo tanto, XSD no hará cumplir ninguna orden. Pero eso no significa que no se pueda engañar a los analizadores para que trabajen rápidamente, así que mantengo la respuesta anterior publicada en caso de que realmente funcione.