我们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万key/value属性对)。在XML文件来自许多不同的来源/工作队和验证一架构。然而,有时 <value/> 节点是这样的:

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

或者这样:

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

要使这种过程速度快,我们使用 外籍 分析XML文件。外籍公开的属性作为一系列-是这样的:

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分析的时间是处理这些属性的通过的名称/string.

整个过程可以加快大幅上升,如果我可以保证/行为的属性(对于初学者来说,没有串的比较 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文件?如果答案是"不"-任何人都可以,也许提出一个替代的,不会随身携带一个巨大的运行性能惩罚?

有帮助吗?

解决方案

根据XML规范,

  

属性规格在开始标记或空元素标签的顺序并不显著

可以在检查部3.1

其他提示

XML属性不的顺序,因此,不存在为了执行。

如果你想要的东西排序,你需要XML元素。什么与XML不同。 JSON,YAML和bEncode,例如同时拥有的地图(其是无序的)和序列(其是有序的)。

正如其他人已经指出,不,你不能依靠属性的顺序。

如果我有任何的进程在所有涉及2 500名XML文件和1.5万key/value对,我会得到这些数据的XML和成一个更加可使用的形式,尽快为我可能会。一个数据库,一个二元化的格式,无论。你没有得到任何优势的使用XML(比其他模式验证)。我要更新我的商店每次我得到了一个新的XML文件,并采取析1.5万XML元素的主流我的过程。

答案的否,唉。我被你的40%的数字感到震惊。我觉得很难相信,转向“富”到ProcessFoo需要那么长。你确定的40%不包括采取时间的执行的ProcessFoo?

是否有可能使用该外籍东西访问按名称的属性?这是访问属性更传统的方式。我不是说这将会更快,但它可能是值得一试。

我不认为XML模式支持 - 属性刚刚定义和按照名称,例如限制他们必须匹配特定的名字 - 但我不看你能怎么定义的XSD这些属性的顺序

我不知道任何其他方式来以特定的顺序一个XML节点上,确保属性 - 不知道任何喜欢的Schematron或其它XML模式机制的RELAX NG将支持....

我敢肯定,有没有办法执行XML文档中的属性顺序。我会假设你可以通过业务流程或其他人为因素,如合同或其他文件就可以了坚持。

如果你只是假定第一属性是“ID”,并测试了名字,来确定?如果是的话,使用的值,如果没有,那么你可以尝试通过名称来获得属性或抛出的文件。

虽然效率不高,通过其序调出属性,你就可以猜到你的数据提供者已经交付XML符合规范的一些非零的次数。的剩下的时间,你可以采取其他行动。

只是一个猜测,但你尝试添加use="required"到每个属性规格?

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

如果解析器正被允许可选属性,当它出现在你的属性将永远在那里减慢我不知道。

再次只是一个猜测。

修改 XML 1.0规范说属性顺序并不显著。 http://www.w3.org/TR/REC-xml/#仲starttags

因此,XSD不会执行任何顺序。但是,这并不意味着解析器不能上当,迅速行动,所以我保持在公布的情况下上面的回答它的实际工作。

据我记得,外籍人士是一个非验证解析器和更好..所以你大概可以放弃该XSD想法。无论是在很多XML的方法(XSD得到了在MSFT的元素顺序诟病颇多赫克回到了一天,例如,通过XML Web服务的亲或反卖家)的顺序依赖是个好主意。

做你的自定义编码和简单地扩展或者您的逻辑,其用于更有效地查找或挖入解析器源。这是小事写编码左右更换高效的工具,而从中屏蔽软件代理商和用户..你想要做这个所以同时保持向后兼容性和可逆性很容易迁移。此外,去固定大小的约束/属性名称翻译。

[认为自己是幸运与外籍:)和其原始速度。试想一下,CLR的开发者是多么爱XML缩放设施,他们经常在的“只是查询数据库”过程中的线路发送200MB ..]

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top