2010-11-20 3 views
2

Ich habe Tausende von SGML-Dokumenten, einige wohlgeformt, einige nicht so gut gebildet. Ich muss bestimmte ELEMENTS in den Dokumenten finden, aber jedes Mal, wenn ich zum Laden gehe und versuche, sie in ein XDocument, XMLDocument oder auch nur einen StreamReader zu lesen, bekomme ich verschiedene XMLException-Fehler.Strategie für die Analyse von Loots und Loots von nicht so gut gebildeten SGML/XML-Dokumenten

Dinge wie "'[' ist ein unerwarteter Token.". Warum? Weil ich ein Dokument mit DOCTYPE wie

<!DOCTYPE RChapter PUBLIC "-//LSC//DTD R Chapter for Authoring//EN" [] > 

haben, und ich habe gelernt, dass die „[]“ etwas gültig innen haben muss. Wiederum kontrolliere ich nicht die Erstellung der Dokumente, aber ich muss sie "knacken" und die Daten bekommen, die ich möchte. Ein weiteres Beispiel ist mit einem "unverschlossenen" ELEMENTE, zum Beispiel:

<Caption>Plants, and facilities<hardhyphen><hyphen>Inspection.</Caption> 

Diese XMLException ist „Der 'Bindestrich' Start-Tag auf der Linie 27 nicht den End-Tag von 'Caption' überein Zeile 27, Position 58.. " Offensichtlich, oder?

Aber dann ist die Frage, wie Sie tatsächlich bestimmte Elemente in diesen Dokumenten bekommen können, ohne XMLExceptions zu begegnen. Ist ein SAX-Parser der richtige Weg? Ich möchte grundsätzlich das Dokument öffnen, direkt zu dem Element gehen, das ich möchte (ohne sich Gedanken darüber machen zu müssen, was in der Nähe wohlgeformt ist oder nicht), die Daten abrufen und weitermachen. Sollte ich nur vergessen, mit XMLDocument Parsen, XDocument und tun nur einfachen String Ersatz wie

str.Replace("<hardhypen><hyphen>", "-") 

und dann versuchen, es in eine der XML-Parser zu laden. Irgendwelche Tipps zu Strategien?

+0

Welche Sprache verwenden Sie? –

+0

Ich kann entweder C# oder VB.NET – Robert4Real

+0

verwenden, wenn es nicht gut gebildet ist, ist es nicht XML und das ist das Problem, das Sie haben. Sie möchten Ihre SGML zuerst in XML umwandeln https://github.com/MindTouch/SGMLReader, http://mmalachowski.blogspot.com/2013/08/performance-test-of-c-html-xpath.html – Jodrell

Antwort

3

Das Problem ist, dass Sie versuchen, SGML mit einem XML-Tool zu analysieren. Sie sind nicht gleich. Wenn Sie ein XML-Tool/eine XML-Sprache für den Zugriff auf die Daten verwenden möchten, müssen Sie wahrscheinlich die SGML-Datei in XML konvertieren, bevor Sie versuchen, sie zu parsen.

Idealerweise verwenden Sie entweder eine Sprache/ein Werkzeug, das SGML unterstützt (wie OmniMark) oder etwas, das "XML-ähnliche" Daten verarbeiten kann (wie Nokogiri aus der ersten Antwort?).

Dies kann ziemlich einfach sein, kann aber an einigen Punkten schwierig werden. Vor allem, wenn Sie über mehrere Doctypes (DTDs) sprechen. (Außerdem gibt es nicht so etwas wie „wohlgeformt“ SGML. Ja, die Elemente/etc. Korrekt verschachtelt werden, aber SGML hat eine DTD zu haben.)

Hier sind einige Unterschiede zwischen SGML und XML mit denen du umgehen müsstest. (Sie möchten diese Route möglicherweise nicht verwenden, aber sie kann für Informationszwecke hilfreich sein.):

  1. DOCTYPE-Deklaration

    Die DOCTYPE-Deklaration in Ihrem Beispiel ist ein perfekt gültiges SGML Doctype. Die [] (interne Teilmenge) muss nichts enthalten. Wenn Sie Deklarationen in der internen Teilmenge haben (normalerweise Entitätsdeklarationen), müssen Sie höchstwahrscheinlich eine Doctype-Deklaration in der XML-Datei beibehalten.

    Das Problem der XML-Parser ist, dass Sie keine System-ID in der Deklaration haben. In einer XML-Doctype-Deklaration ist die System-ID erforderlich, wenn eine öffentliche ID vorhanden ist. In einer SGML-Doctype-Deklaration ist dies nicht erforderlich.

    Fazit: Wenn Sie nicht möchten, dass XML in eine DTD/ein Schema zerlegt wird oder Deklarationen in der internen Teilmenge haben, entfernen Sie die Doctype-Deklaration. Wenn die XML-Datei gültig sein muss, müssen Sie mindestens eine System-ID hinzufügen. Vergessen Sie nicht, die Verarbeitungsanweisung <?xml ...?> hinzuzufügen.

  2. Elemente ohne Endtags

    Die <hardhyphen> und <hyphen> Elemente gelten SGML. Mit SGML-DTDs können Sie die Minimierung von Tags festlegen. Dies bedeutet, dass Sie angeben können, ob ein End-Tag erforderlich ist. (Sie können auch den Start-Tag optional machen, aber das ist verrückt reden.) In XML Sie diese Elemente zu schließen haben (wie <hardhyphen/> oder <hardhyphen></hardhyphen>)

    Das Beste, was zu tun ist, um Ihren SGML-DTD schauen und sehen, welche Elemente habe optionale End-Tags. Die Tag-Minimierung wird direkt hinter dem Elementnamen in der Elementdeklaration angegeben. Ein '-' bedeutet, dass das Tag erforderlich ist. Ein 'o' (Buchstabe 'oh') bedeutet, dass das Tag optional ist. Wenn Sie beispielsweise <!ELEMENT hyphen - o (#PCDATA)> sehen, bedeutet dies, dass das Start-Tag erforderlich ist (-) und das End-Tag optional ist (o). Wenn Sie <!ELEMENT hyphen - - (#PCDATA)> sehen, ist sowohl das Start- als auch das End-Tag erforderlich.

    Fazit: richtig alle Elemente schließen, die nicht Endtags

  3. Verarbeitungshinweise

    Verarbeitungshinweise (PI) in SGML haben nicht die zweite ? haben, wenn sie geschlossen sind, wie XML tut es. Sie müssen die zweite ? hinzufügen.

    Beispiel SGML PI: <?asdf jkl>

    Beispiel XML PI: <?asdf jkl?>

  4. enthalten/

    Sie werden wahrscheinlich nicht kümmern, aber in einer SGML-DTD können Sie angeben, in eine Elementdeklaration, dass ein anderes Element irgendwo innerhalb dieses Elements erlaubt ist (oder nicht erlaubt). Dies kann sehr schmerzhaft sein, wenn das Ziel-XML eine DTD analysieren muss. XML-DTDs erlauben keine Einschlüsse/Ausschlüsse.Diese

    ist, was eine Einbeziehung könnte wie folgt aussehen:

    <!ELEMENT chapter - - (section)+ +(revst|revend)>

    Dieses sagt, dass revst oder revend sind überall innerhalb von chapter erlaubt. Wenn die Elementdeklaration -(revst|revend) hätte, würde dies bedeuten, dass revst oder revendnicht überall in chapter zulässig ist.

Hoffe, das hilft.

1

Ja, verwenden Sie Nokogiri.

Scrollen Sie auf dieser Seite ein wenig nach unten und kopieren Sie den Code unter "Synopsis" in eine Datei, sagen Sie xml-parser.rb. Wenn Sie sich auf einem Mac befinden (Ruby ist bereits auf Macs installiert), führen Sie von Terminal aus gem install nokogiri aus, und führen Sie die Datei dann mit der folgenden Datei aus: .

Sie können auch irb direkt vom Terminal und dann require 'nokogiri' eingeben und in Echtzeit mit dem nokogiri api spielen. Ich muss interaktiven Ruby lieben. :)

Wenn Sie unter Windows sind, versuchen Sie dies Ruby installer for Windows.

Verwandte Themen