19

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

完全なアプリケーション構成は、これらの XML ファイル (150 万を超えるキーと値の属性のペアに変換されます) の約 2500 で構成されます。XML ファイルは、さまざまなソース/チームから取得され、スキーマに対して検証されます。ただし、<value/>ノードが次のようになる場合があります。

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

またはこれ:

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

このプロセスを高速化するために、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);
 }
}

ProcessAttribute()これにより、「キー」を読み取り、値をどうするかを決定する すべての責任が関数に置かれます。アプリをプロファイリングすると、合計 XML 解析時間の約 40% が名前/文字列によってこれらの属性を処理していることが示されました。

属性の順序を保証/強制できれば、プロセス全体を劇的に高速化できます (まず、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 ドキュメントで属性の順序を強制する方法はありますか? 答えが「いいえ」の場合、実行時のパフォーマンスに大きなペナルティをもたらさない代替案を誰かが提案できますか?

4

8 に答える 8

37

xml仕様によると、

start-tag または empty-element タグ内の属性指定の順序は重要ではありません

セクション3.1で確認できます

于 2009-11-05T17:28:37.420 に答える
6

XML 属性には順序がないため、強制する順序はありません

順序付けが必要な場合は、XML 要素が必要です。または、XML とは別のものです。JSON、YAML、および bEncode には、たとえば、マップ (順序付けされていない) とシーケンス (順序付けられている) の両方があります。

于 2009-11-05T19:12:14.963 に答える
2

残念ながら、答えノーです。40%という数字にビックリです。「foo」を ProcessFoo に変換するのにそれほど時間がかかるとは信じがたいです。40% には ProcessFoo の実行にかかる時間が含まれていませんか?

この Expat を使用して名前で属性にアクセスすることは可能ですか? これは、属性にアクセスするためのより伝統的な方法です。速くなるとは言いませんが、試してみる価値はあります。

于 2009-11-05T17:26:04.460 に答える
1

XML スキーマがそれをサポートしているとは思わない - 属性は単に定義され、名前によって制限されている.

XMLノードの属性が特定の順序で来ることを確認する他の方法を知りません.SchematronやRelax NGなどの他のXMLスキーマメカニズムがそれをサポートするかどうかはわかりません....

于 2009-11-05T17:22:35.187 に答える
1

XML ドキュメントで属性の順序を強制する方法はないと確信しています。ビジネス プロセスやその他の人的要因 (契約書やその他の文書など) を介して主張できると仮定します。

最初の属性が「id」であると想定し、名前をテストして確認したらどうでしょうか? はいの場合は値を使用し、そうでない場合は、名前で属性を取得するか、ドキュメントを破棄してみてください。

序数で属性を呼び出すほど効率的ではありませんが、データ プロバイダーが XML を仕様どおりに提供したことを推測できる回数はゼロではありません。残りの時間は、他のアクションを実行できます。

于 2009-11-05T17:25:00.120 に答える
0

私が覚えていることから、Expatは非検証パーサーであり、それにより優れています..そのため、おそらくそのXSDのアイデアを破棄できます。多くの XML アプローチでは、順序に依存することも良い考えではありません (たとえば、MSFT の XML Web サービスの売り手または反対者によって、XSD は要素の順序について非常に多くの批判を受けました)。

カスタム エンコーディングを実行し、より効率的なルックアップのためにロジックを拡張するか、パーサー ソースを掘り下げるだけです。ソフトウェアエージェントとユーザーを保護しながら、効率的な置換をエンコードするツールを作成するのは簡単です.これを行うことで、下位互換性と可逆性を維持しながら簡単に移行できます. また、固定サイズの制約/属性名の変換に進みます。

[ Expat :) とその生の速度で幸運だと考えてください。CLR 開発者が XML スケーリング機能をどのように気に入っているか想像してみてください。彼らは「データベースにクエリを実行するだけ」の過程で定期的に 200MB を送信します..]

于 2009-11-05T17:38:48.053 に答える
0

推測ですが、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/#sec-starttags

したがって、XSD は順序を強制しません。しかし、それはパーサーがだまされてすぐに動作しないという意味ではありません。したがって、実際に動作する場合に備えて、上記の回答を公開しておきます。

于 2009-11-05T17:23:28.803 に答える