Nuestra C++ lee los datos de configuración de archivos XML que ser algo como esto:¿Puedo hacer cumplir el orden de los atributos XML utilizando un esquema?
<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 de la aplicación completa consisten en ~ 2500 de estos archivos XML (que se traduce en más de 1,5 millones de clave/valor pares de atributos) . Los archivos XML provienen de diferentes fuentes/equipos y se validan contra un esquema. Sin embargo, a veces los nodos <value/>
este aspecto:
<value name="bar1" id="BAR1" description="the bar" size="20" ... />
o esto:
<value id="BAT1" description="the bat" name="bat1" size="25" ... />
Para hacer este proceso rápido, estamos utilizando Expat para analizar los documentos XML. Expatriados expone los atributos como un conjunto - como este:
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 a nuestra función ProcessAttribute()
a leer la 'llave' y decidir qué hacer con el valor. La creación de perfiles de la aplicación ha demostrado que ~ 40% del tiempo total de análisis XML trata estos atributos por nombre/cadena.
El proceso general podría acelerarse drásticamente si pudiera garantizar/hacer cumplir el orden de los atributos (para los principiantes, no hay comparaciones de cadenas en ProcessAttribute()
). Por ejemplo, si el atributo 'id' era siempre la primera atributo que podría tratar con él 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 de esquema del W3C, puedo usar <xs:sequence>
en un esquema XML para hacer cumplir la orden de los elementos - pero no parece trabajar por atributos - o tal vez 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 una manera de hacer cumplir el orden atributo en un documento XML? Si la respuesta es "no", ¿alguien podría sugerir una alternativa que no conlleve una gran penalización de rendimiento en el tiempo de ejecución?
Por qué fue usted con atributos y no foo1 foo1 Esta es la descripción description> ? Puede especificar el orden de los elementos, entonces, ¿por qué no usarlos? –
jmucchiello
+1 Esta es una pregunta muy bien escrita (e interesante). –