Domanda

Ho migliaia di documenti SGML, alcuni ben formato, alcuni non così ben formato. Ho bisogno di ottenere in certi elementi nei documenti, ma ogni volta che vado a carico e cerco di leggerli in un XDocument, XMLDocument, o anche solo uno StreamReader, ricevo diverse vari errori XmlException.

Cose come " '[' è un token imprevisto.". Perché? Perché ho un documento con DOCTYPE come

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

e ho imparato che le "[]" ha bisogno di avere qualcosa dentro valido. Anche in questo caso, non controllare la creazione dei documenti, ma devo "crack" di loro e ottenere i dati che voglio. Un altro esempio sta avendo un "non chiusa" ELEMENTO, ad esempio:

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

Questa XmlException è "La 'trattino' inizio tag sulla linea 27 non corrisponde al tag di fine 'Caption'. Linea 27, la posizione 58." Ovvio, no?

Ma allora la domanda è: come si può effettivamente arrivare a certi elementi in questi documenti, senza incontrare XMLExceptions. È un parser SAX nel modo giusto? Io fondamentalmente voglio aprire il documento, andare a destra per l'elemento che voglio (senza preoccuparsi quello che potrebbe o non potrebbe essere ben formato nelle vicinanze), estrarre i dati, e andare avanti. Devo solo dimenticare parsing con XMLDocument, XDocument, e solo fare semplici sostituzioni di stringa come

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

e quindi provare a caricarlo in uno dei parser XML. Eventuali suggerimenti su strategie?

È stato utile?

Soluzione

Il problema è che si sta cercando di analizzare SGML con uno strumento XML. Non sono la stessa cosa. Se si desidera utilizzare un XML strumento / lingua per accedere ai dati, si avrà probabilmente bisogno di convertire lo SGML in XML prima di tentare di analizzarlo.

Idealmente si sarebbe utilizzare un linguaggio / strumento che supporta SGML (come OmniMark) o qualcosa che in grado di gestire "XML come" i dati (come nokogiri dalla prima risposta?).

Questo può essere piuttosto semplice, ma può diventare difficile in alcuni punti. Soprattutto se si sta parlando di più DOCTYPE (DTD). (Inoltre, non c'è cosa come SGML "ben formato". Sì, gli elementi / ecc. Devono essere annidati correttamente, ma SGML ha per avere un DTD.)

Qui ci sono alcune differenze tra SGML e XML che si avrebbe bisogno di gestire. (Non si può decidere di seguire questa strada, ma può essere utile a scopo informativo comunque.):

  1. dichiarazione DOCTYPE

    La dichiarazione DOCTYPE nel tuo esempio è un doctype SGML perfettamente valido. Il [] (sottoinsieme interno) non deve avere nulla in esso. Se si dispone di dichiarazioni nel sottoinsieme interno (di solito dichiarazioni di entità), è molto più che probabile andando ad avere per mantenere una dichiarazione DOCTYPE nel XML.

    La questione del parser XML sta avendo è che non si dispone di un identificatore di sistema nella dichiarazione. In una dichiarazione DOCTYPE XML, l'identificatore di sistema è necessario se v'è un identificatore pubblico. In una dichiarazione SGML doctype, non è richiesto.

    Linea di fondo : a meno che non è necessario l'XML per analizzare ad un DTD / Schema o hanno dichiarazioni nel sottoinsieme interno, nudo la dichiarazione DOCTYPE. Se l'XML non deve essere valido, sarete almeno necessità di aggiungere un identificatore di sistema. Non dimenticate di aggiungere l'istruzione di elaborazione <?xml ...?>.

  2. Elementi senza fine tag

    Il <hardhyphen> e <hyphen> elementi sono validi SGML. SGML DTD permettono di specificare tag minimizzazione. Ciò significa che è possibile specificare se è richiesto un tag di chiusura. (Si può anche fare il tag iniziale facoltativa, ma questo è discorso folle.) In XML è necessario chiudere questi elementi (come <hardhyphen/> o <hardhyphen></hardhyphen>)

    La cosa migliore da fare è di guardare il vostro SGML DTD e vedere quali elementi hanno tag di chiusura opzionali. La minimizzazione tag è specificato subito dopo il nome dell'elemento nella dichiarazione elemento. A '-' significa che è necessario il tag. Un 'o' (lettera 'oh') significa che il tag è opzionale. Per esempio se si vede <!ELEMENT hyphen - o (#PCDATA)>, questo significa che è richiesta la tag di apertura (-) e il tag di chiusura è opzionale (o). Se si vede <!ELEMENT hyphen - - (#PCDATA)>, sono necessari sia l'inizio e il tag di chiusura.

    Linea di fondo : chiudere correttamente tutti gli elementi che non hanno fine i tag

  3. istruzioni di elaborazione

    Le istruzioni di elaborazione (PI di) in SGML non hanno il secondo ? quando sono chiuse come XML fa. Avrai bisogno di aggiungere il secondo ?.

    Esempio SGML PI: <?asdf jkl>

    Esempio XML PI: <?asdf jkl?>

  4. Inclusioni / Esclusioni

    Probabilmente non dovrà preoccuparsi di questo, ma in uno SGML DTD è possibile specificare in una dichiarazione di elemento che un altro elemento è consentito in qualsiasi punto all'interno di tale elemento (o non ammessi). Questo può essere un dolore se il vostro XML di destinazione ha bisogno di analizzare ad un DTD; XML DTD di non consentono inclusioni / esclusioni.

    Questo è ciò che un inserimento potrebbe essere simile:

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

    Questo sta dicendo che revst o revend sono ammessi in qualsiasi punto all'interno della chapter. Se la dichiarazione elemento aveva -(revst|revend), vorrebbe dire che revst o revend è non ammessi in qualsiasi punto all'interno della chapter.

Spero che questo aiuti.

Altri suggerimenti

Si, utilizzare Nokogiri .

Scorrere verso il basso un po 'su quella pagina e copiare il codice sotto "Synopsis" in un file, ad esempio xml-parser.rb. Quindi, se siete su un Mac (Rubino viene già installato su Mac.), Dal Terminal, gem install nokogiri correre, e quindi eseguire il file con:. ruby xml-parser.rb

Si può anche digitare irb direttamente dal terminale e poi require 'nokogiri' e iniziare a giocare con l'API nokogiri in tempo reale. Gotta love Rubino interattivo. :)

Se siete su Windows, provate questo href="http://rubyinstaller.org/" rel="nofollow noreferrer"> installatore .

scroll top