Frage

Unsere C ++ Anwendung liest Konfigurationsdaten aus XML-Dateien, die wie folgt aussehen:

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

Die vollständige Anwendungskonfiguration besteht aus ~ 2500 diesen XML-Dateien (die in mehr als 1,5 Millionen Schlüssel / Wert übersetzt Attributpaare). Die XML-Dateien aus vielen verschiedenen Quellen / Teams und werden gegen ein Schema validiert. Aber manchmal die <value/> Knoten wie folgt aussehen:

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

oder folgt aus:

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

Um diesen Prozess schnell zu machen, die wir verwenden Expat die XML-Dokumente zu analysieren. Expat macht die Attribute als Array - wie folgt aus:

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

Damit liegt die ganze Verantwortung auf unsere ProcessAttribute() Funktion den ‚Schlüssel‘ zu lesen und entscheiden, was mit dem Wert zu tun. die App Profilierungs hat gezeigt, dass ca. 40% der gesamten XML-Parsing Zeit wird nach Namen / string mit diesen Attributen handelt.

Der Gesamtprozess dramatisch beschleunigt werden könnte, wenn ich könnte die Reihenfolge der Attribute (für den Anfang, keine String-Vergleiche in ProcessAttribute()) garantieren / erzwingen. Wenn beispielsweise ‚id‘ Attribut ist immer das erste Attribut wir damit umgehen konnten direkt:

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

Nach den W3C-Schema-Spezifikationen, ich <xs:sequence> in einem XML-Schema können Sie die Reihenfolge der Elemente erzwingen - aber es scheint nicht für Attribute zu arbeiten - oder vielleicht ist es verwende ich falsch:

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

Gibt es eine Möglichkeit, um Attribut in einem XML-Dokument zu erzwingen? Wenn die Antwort „nein“ ist - könnte jemand vielleicht eine Alternative vorschlagen, die nicht eine große Laufzeitleistungseinbuße führen würden

War es hilfreich?

Lösung

Nach der XML-Spezifikation,

  

die Reihenfolge von Attributspezifikationen in einem Start-Tag oder Leeres-Element-Tag ist nicht signifikant

Sie können es unter Abschnitt 3.1

Andere Tipps

XML-Attribute nicht Haben ein Auftrag, daher gibt es keine Ordnung zu erzwingen.

Wenn Sie etwas bestellen möchten, müssen Sie XML-Elemente. Oder etwas anderes XML. JSON, YAML und bEncode, z.B. haben beide Karten (die ungeordnete sind) und Sequenzen (die bestellt werden).

Wie andere haben darauf hingewiesen, nein, man kann nicht auf Attribut Bestellung verlassen.

Wenn ich überhaupt einen Prozess hatte beteiligt 2500 XML-Dateien und 1.500.000 Schlüssel / Wert-Paare, würde ich diese Daten erhalten aus XML und in eine nutzbare Form so schnell wie ich nur konnte. Eine Datenbank, ein binäres Serialisierung Format, was auch immer. Sie bekommen keinen Vorteil aus XML (andere als Schema-Validierung) zu verwenden. Ich würde meinen Speicher jedes Mal aktualisieren ich eine neue XML-Datei erhalten, und nehmen 1,5 Millionen XML-Elemente aus dem Hauptstrom meines Verfahrens Parsen.

Die Antwort ist Nein, leider. Ich bin von Ihrer 40% Figur schockiert. Ich finde es schwer zu glauben, dass „foo“ in ProcessFoo dauert so lange drehen. Sind Sie sicher, dass das 40% nicht die Zeit umfasst, die zum Ausführen ProcessFoo?

Ist es möglich, die Attribute von Namen mit dieser Expat Sache zugreifen? Das ist die traditionelle Art und Weise Attribute zuzugreifen. Ich sage nicht, es schneller sein wird, aber es könnte einen Versuch wert sein.

Ich glaube nicht, XML Schema unterstützt, dass - Attribute werden nur durch Namen definiert und eingeschränkt, zum Beispiel sie haben einen bestimmten Namen entsprechen - aber ich sehe nicht, wie Sie eine Bestellung für diese Attribute in XSD definieren könnten

.

Ich weiß nicht, von irgendeiner anderen Art und Weise sicher, dass Attribute auf einem XML-Knoten in einer bestimmten Reihenfolge werden zu lassen - nicht sicher, ob alle anderen XML-Schema-Mechanismen wie Schematron oder NG dass Relax unterstützen würde ....

Ich bin mir ziemlich sicher, dass es keine Möglichkeit, Attribut, um in einem XML-Dokument zu erzwingen. Ich gehe davon aus, dass Sie auf sie über einen Geschäftsprozess oder andere menschliche Faktoren, wie ein Vertrag oder eine anderes Dokument bestehen können.

Was ist, wenn Sie gerade davon ausgegangen, dass das erste Attribut war „id“ und testete den Namen sicher zu sein? Wenn ja, den Wert verwenden, wenn nicht, dann können Sie versuchen, das Attribut nach dem Namen zu bekommen oder das Dokument werfen.

Während nicht so effizient wie der Aufruf das Attribut durch seine Ordnungs aus, einige Nicht-Null-Anzahl, wie oft werden Sie in der Lage sein, zu erraten, dass Ihre Datenanbieter XML geliefert spec. Der Rest der Zeit, können Sie andere Maßnahmen ergreifen.

Nur eine Vermutung, aber können Sie use="required" jedem Ihrer Attribut Spezifikationen Versuchen Sie?

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

Ich frage mich, ob der Parser, indem optionale Attribute verlangsamt wird, wenn es Ihre Attribute erscheint immer da sein werden.

Wieder nur eine Vermutung.

EDIT: XML 1.0-Spezifikation besagt, dass Attribut, um nicht von Bedeutung ist. http://www.w3.org/TR/REC-xml/# sec-starttags

Daher XSD wird keine Reihenfolge erzwingen. Aber das bedeutet nicht, dass Parser können nicht in Arbeit schnell täuschen lassen, so dass ich halte die oben genannte Antwort, falls veröffentlichte es tatsächlich funktioniert.

Von dem, was ich mich erinnere, ist Expat ein nicht Validieren Parser und besser für sie .. so können Sie wahrscheinlich Schrott, dass XSD Idee. Weder ist die auftragsabhängig eine gute Idee, in vielen XML-Ansätze (XSD auf Element, um kritisiert habe eine verdammt viel zurück in den Tag, zum Beispiel durch Pro oder anti- Verkäufer von XML Web Services bei MSFT).

Sie Ihre benutzerdefinierte Codierung und einfach erweitern entweder Ihre Logik für eine effizientere Lookup oder graben sich in den Parser-Quelle. Es ist trivial, die Ausrüstung um Codierung effizienter Ersatz während Abschirmen der Software-Agenten und Benutzer zu schreiben .. Sie dies tun wollen, so ist es leicht migriert, während die Rückwärtskompatibilität und Reversibilität zu bewahren. Auch geht für feste Größe Einschränkungen / Attribut-name-Übersetzung.

[Betrachten Sie sich mit Expat :) und seiner rohen Geschwindigkeit Glück. Stellen Sie sich vor, wie CLR Devs XML Skalierungsmöglichkeiten lieben, sie routinemäßig 200 MB auf dem Draht in Prozess der ‚nur die Abfrage der Datenbank‘ senden ..]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top