我可以使用模式强制执行XML属性的顺序吗?

Mik*_*kes 17 xml performance xsd expat-parser

我们的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>
Run Code Online (Sandbox Code Playgroud)

完整的应用程序配置包含大约2500个这些XML文件(转换为超过150万个键/值属性对).XML文件来自许多不同的源/团队,并根据模式进行验证.但是,有时<value/>节点看起来像这样:

<value name="bar1" id="BAR1" description="the bar" size="20" ... />
Run Code Online (Sandbox Code Playgroud)

或这个:

<value id="BAT1" description="the bat" name="bat1"  size="25" ... />
Run Code Online (Sandbox Code Playgroud)

为了快速完成此过程,我们使用Expat来解析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);
 }
}
Run Code Online (Sandbox Code Playgroud)

这将所有责任都放在我们的ProcessAttribute()功能上,以阅读"密钥"并决定如何处理该值. 对应用程序进行概要分析表明,XML解析总时间的约40%是按名称/字符串处理这些属性.

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

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.
}
Run Code Online (Sandbox Code Playgroud)

根据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>
Run Code Online (Sandbox Code Playgroud)

有没有办法在XML文档中强制执行属性顺序?如果答案是"否" - 有人可能会提出一个不会带来巨大的运行时性能损失的替代方案吗?

Sta*_*nov 34

根据xml规范,

start-tag或empty-element标记中的属性规范的顺序并不重要

你可以在3.1节查看


Jör*_*tag 6

XML属性不具备的订单,因此没有订单执行.

如果您想要订购的东西,则需要XML元素.或者与XML不同的东西.JSON,YAML和bEncode,例如有两个映射(无序)和序列(有序).


Rob*_*ney 5

正如其他人指出的那样,不,您不能依赖属性排序。

如果我有任何涉及 2,500 个 XML 文件和 150 万个键/值对的流程,我会尽快将这些数据从 XML 中取出并转换为更可用的形式。数据库、二进制序列化格式等等。使用 XML(除了模式验证之外)并没有获得任何好处。每次获得新的 XML 文件时,我都会更新我的商店,并从流程的主要流程中解析 150 万个 XML 元素。