Могу ли я применить порядок атрибутов XML с помощью схемы?

Наше приложение C ++ считывает данные конфигурации из файлов XML, которые выглядят примерно так:

<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>

Полная конфигурация приложения состоит из ~ 2500 этих XML-файлов (что означает более 1,5 миллиона пар ключ / значение атрибута). Файлы XML поступают из разных источников / команд и проверяются на соответствие схеме. Однако иногда<value/> узлы выглядят так:

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

или это:

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

Чтобы сделать этот процесс быстрым, мы используемэмигрант разобрать документы XML. Expat предоставляет атрибуты в виде массива, например:

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);
 }
}

Это возлагает всю ответственность на нашихProcessAttribute() Функция, чтобы прочитать «ключ» и решить, что делать со значением.Профилирование приложения показало, что ~ 40% общего времени анализа XML связано с этими атрибутами по имени / строке.

Весь процесс мог бы быть значительно ускорен, если бы я мог гарантировать / обеспечить порядок атрибутов (для начала, нет сравнения строк вProcessAttribute()). Например, если атрибут 'id' былвсегда 1-й атрибут, с которым мы могли бы иметь дело напрямую:

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.
}

В соответствии со спецификациями схемы W3C, я могу использовать<xs:sequence> в XML-схеме для обеспечения порядка элементов - но, похоже, он не работает для атрибутов - или, возможно, я использую его неправильно:

<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>

Есть ли способ обеспечить порядок атрибутов в документе XML? Если ответ «нет», может кто-нибудь предложить альтернативу, которая не будет иметь огромных потерь производительности во время выполнения?

Ответы на вопрос(8)

Ваш ответ на вопрос