Question

J'ai des milliers de documents de SGML, un certain bien formé, d'autres pas si bien formé. Je dois obtenir à certains éléments contenus dans les documents, mais chaque fois que je vais à la charge et essayer de les lire dans un XDocument, XMLDocument, ou même juste un StreamReader, je reçois différentes diverses erreurs de XMLException.

Des choses comme « « [ » est un jeton inattendu. ». Pourquoi? Parce que j'ai un document avec DOCTYPE comme

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

et j'ai appris que les « [] » doit avoir quelque chose de valable à l'intérieur. Encore une fois, je ne contrôle pas la création des documents, mais je dois le « crack » et les obtenir les données que je veux. Un autre exemple est d'avoir un élément « non fermé », par exemple:

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

Cette XMLException est « Le « trait d'union » Balise ouvrante la ligne 27 ne correspond pas à la balise de fin de la « Légende ». Ligne 27, la position 58. » Evident, non?

Mais la question est de savoir comment pouvez-vous obtenir effectivement à certains éléments de ces documents, sans rencontrer XMLExceptions. Est un analyseur SAX la bonne façon? Je veux essentiellement d'ouvrir le document, allez à l'élément que je veux (sans se soucier de ce qui pourrait ou ne pourrait pas être bien formé à proximité), extraire les données et passer à autre chose. Dois-je oublier que l'analyse syntaxique avec XMLDocument, XDocument, et il suffit de faire des remplacements de cordes simples comme

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

et puis essayer de le charger dans l'un des parseurs XML. Des conseils sur les stratégies?

Était-ce utile?

La solution

Le problème est que vous essayez d'analyser SGML avec un outil XML. Ils ne sont pas les mêmes. Si vous souhaitez utiliser un outil XML / langue pour accéder aux données, vous aurez probablement besoin de convertir le SGML à XML avant d'essayer de l'analyser.

Idéalement vous auriez soit utiliser un langage / outil supports SGML (comme OmniMark) ou quelque chose qui peut gérer « XML comme » les données (comme nokogiri de la première réponse?).

Cela peut être assez simple, mais peut être difficile à certains points. Surtout si vous parlez de plusieurs doctypes (DTD). (En outre, il n'y a pas une telle chose comme "bien formé" SGML. Oui, les éléments / etc. Doivent être correctement imbriquées mais SGML a pour avoir une DTD.)

Voici quelques différences entre SGML et XML que vous auriez besoin de gérer. (Vous voudrez peut-être de ne pas aller dans cette voie, mais il peut être utile à des fins d'information de toute façon.):

  1. déclaration DOCTYPE

    La déclaration DOCTYPE dans votre exemple est un type de document SGML parfaitement valide. Le [] (sous-ensemble interne) ne doit pas avoir quoi que ce soit en elle. Si vous avez des déclarations dans le sous-ensemble interne (généralement les déclarations d'entités), vous êtes plus que probable d'avoir à garder une déclaration DOCTYPE dans le fichier XML.

    La question de l'analyseur XML est d'avoir est que vous ne disposez pas d'un identifiant de système dans la déclaration. Dans une déclaration XML doctype, l'identifiant du système est nécessaire s'il y a un identifiant public. Dans une déclaration DOCTYPE SGML, il est pas nécessaire.

    Bottom line : à moins que vous avez besoin du XML pour analyser un DTD / schéma ou contenir des déclarations dans le sous-ensemble interne, la bande la déclaration DOCTYPE. Si le XML ne doit être valide, vous aurez au moins besoin d'ajouter un identifiant de système. Ne pas oublier d'ajouter l'instruction de traitement <?xml ...?>.

  2. Éléments sans fin balises

    Les éléments de <hardhyphen> et <hyphen> sont SGML valide. de SGML DTD vous permettent de spécifier la minimisation de l'étiquette. Ce que cela signifie est que vous pouvez spécifier si oui ou non une balise de fin est nécessaire. (Vous pouvez également faire la balise de début en option, mais c'est fou de parler.) En XML, vous devez fermer ces éléments (comme <hardhyphen/> ou <hardhyphen></hardhyphen>)

    La meilleure chose à faire est de regarder votre DTD SGML et voir quels éléments ont les balises de fin en option. La minimisation de l'étiquette est spécifié juste après le nom de l'élément dans la déclaration d'élément. A « - » signifie l'étiquette est nécessaire. Un « o » (lettre « oh ») signifie que l'étiquette est facultative. Par exemple, si vous voyez <!ELEMENT hyphen - o (#PCDATA)>, cela signifie que la balise de début est nécessaire (-) et la balise de fin est facultative (o). Si vous voyez <!ELEMENT hyphen - - (#PCDATA)>, le début et les balises de fin sont nécessaires.

    Bottom line : fermer correctement tous les éléments qui ne sont pas fin balises

  3. Instructions Traitement

    instructions de traitement (PI) lors des SGML ne pas la deuxième ? quand ils sont fermés comme XML fait. Vous aurez besoin d'ajouter la deuxième ?.

    Exemple SGML PI: <?asdf jkl>

    Exemple XML PI: <?asdf jkl?>

  4. Inclusions / Exclusions

    Vous ne sera probablement pas à vous soucier de cela, mais dans une DTD SGML vous pouvez spécifier dans une déclaration d'élément qu'un autre élément est autorisé partout à l'intérieur de cet élément (ou non autorisé). Cela peut être une douleur si votre XML cible doit analyser à une DTD; de DTD XML ne permettent pas d'inclusions / exclusions.

    est ce que l'inclusion pourrait ressembler à:

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

    dit que revst ou revend sont autorisés partout à l'intérieur de chapter. Si la déclaration d'élément avait -(revst|revend), cela signifierait que revst ou revend est pas autorisés partout à l'intérieur de chapter.

Hope this helps.

Autres conseils

Oui, utiliser Nokogiri .

Faites défiler un peu sur cette page et copiez le code sous la rubrique « Synopsis » dans un fichier, par exemple xml-parser.rb. Ensuite, si vous êtes sur un Mac (Ruby vient déjà installé sur Mac.), Du Terminal, exécutez gem install nokogiri, puis exécutez le fichier avec:. ruby xml-parser.rb

Vous pouvez également taper le bouton droit de irb du terminal puis require 'nokogiri' et commencer à jouer avec l'api nokogiri en temps réel. Gotta love Ruby interactive. :)

Si vous êtes sous Windows, essayez cette installer Ruby pour Windows .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top