我可以使用模式强制 XML 属性的顺序吗? [英] Can I enforce the order of XML attributes using a schema?

查看:8
本文介绍了我可以使用模式强制 XML 属性的顺序吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的 C++ 应用程序从如下所示的 XML 文件中读取配置数据:

Our C++ application reads configuration data from XML files that look something like this:

<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 文件组成(转换为超过 150 万个键/值属性对).XML 文件来自许多不同的来源/团队,并根据模式进行验证.但是,有时 <value/> 节点看起来像这样:

The complete application configuration consist of ~2500 of these XML files (which translates into more than 1.5 million key/value attribute pairs). The XML files come from many different sources/teams and are validated against a schema. However, sometimes the <value/> nodes look like this:

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

或者这个:

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

为了加快这个过程,我们使用 Expat 来解析 XML 文档.Expat 将属性公开为数组 - 如下所示:

To make this process fast, we are using Expat to parse the XML documents. Expat exposes the attributes as an array - like this:

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 解析总时间是按名称/字符串处理这些属性.

This puts all the responsibility onto our ProcessAttribute() function to read the 'key' and decide what to do with the value. Profiling the app has shown that ~40% of the total XML Parsing time is dealing with these attributes by name/string.

如果我可以保证/强制执行属性的顺序(对于初学者,ProcessAttribute() 中没有字符串比较),整个过程可以大大加快.例如,如果 'id' 属性是 always 第一个属性,我们可以直接处理它:

The overall process could be sped up dramatically if I could guarantee/enforce the order of the attributes (for starters, no string comparisons in ProcessAttribute()). For example, if 'id' attribute was always the 1st attribute we could deal with it directly:

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 模式规范,我可以在 XML 模式中使用 <xs:sequence> 来强制元素的顺序 - 但它似乎不适用于属性 - 或者也许我用错了:

According to the W3C schema specs, I can use <xs:sequence> in an XML schema to enforce the order of elements - but it doesn't seem to work for attributes - or perhaps I'm using it incorrectly:

<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 文档中强制执行属性顺序?如果答案是否" - 任何人都可以提出一个不会带来巨大运行时性能损失的替代方案吗?

Is there a way to enforce attribute order in an XML document? If the answer is "no" - could anyone perhaps suggest a alternative that wouldn't carry a huge runtime performance penalty?

推荐答案

根据xml规范,

开始标签或空元素标签中属性说明的顺序并不重要

the order of attribute specifications in a start-tag or empty-element tag is not significant

您可以在 第 3.1 节

这篇关于我可以使用模式强制 XML 属性的顺序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆