Стратегия синтаксического анализа LOTS и LOTS не очень хорошо сформированных документов SGML / XML - PullRequest
2 голосов
/ 20 ноября 2010

У меня есть тысячи документов SGML, некоторые из которых хорошо сформированы, некоторые не так хорошо сформированы.Мне нужно получить некоторые элементы в документах, но каждый раз, когда я загружаюсь и пытаюсь прочитать их в XDocument, XMLDocument или даже просто в StreamReader, я получаю разные ошибки XMLException.

Такие вещи, как "'[' - неожиданный токен."Зачем?Потому что у меня есть документ с DOCTYPE, например

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

, и я узнал, что в «[]» должно быть что-то допустимое внутри.Опять же, я не контролирую создание документов, но я ДОЛЖЕН «взломать» их и получить нужные мне данные.Другой пример - наличие «незамкнутого» ЭЛЕМЕНТА, например:

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

Это исключение XMLEx: «Начальный тег« дефис »в строке 27 не соответствует конечному тегу« Заголовок ». Строка 27, позиция58.»Очевидно, верно?

Но тогда возникает вопрос, как на самом деле вы можете получить некоторые элементы в этих документах, не встречая исключений XMLE?Является ли SAX-парсер правильным способом?Я в основном хочу открыть документ, перейти прямо к нужному элементу (не беспокоясь о том, что может быть, а может и не быть правильно сформированным рядом), вытащить данные и двигаться дальше.Должен ли я просто забыть синтаксический анализ с XMLDocument, XDocument и просто выполнить простые замены строк, такие как

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

, а затем попытаться загрузить его в один из синтаксических анализаторов XML.Любые советы по стратегиям?

Ответы [ 2 ]

3 голосов
/ 20 ноября 2010

Проблема в том, что вы пытаетесь проанализировать SGML с помощью инструмента XML.Они не одинаковы.Если вы хотите использовать инструмент / язык XML для доступа к данным, вам, вероятно, потребуется преобразовать SGML в XML, прежде чем пытаться его проанализировать.

В идеале вы должны использовать язык / инструмент, поддерживающий SGML (например, OmniMark), или что-то, что может обрабатывать данные типа XML (например, nokogiri из первого ответа?).

Этоможет быть довольно прямым, но может стать сложным в некоторых моментах.Особенно, если вы говорите о нескольких типах (DTD).(Также нет такого понятия, как «правильно сформированный» SGML. Да, элементы и т. Д. Должны быть правильно вложены, но SGML имеет , чтобы иметь DTD.)

Вотнекоторые различия между SGML и XML, с которыми вам нужно справиться.(Возможно, вы не захотите идти по этому пути, но в любом случае это может быть полезно в информационных целях.):

  1. Объявление DOCTYPE

    DOCTYPEОбъявление в вашем примере является совершенно допустимым типом документа SGML.[] (внутреннее подмножество) не должно содержать ничего.Если у вас есть объявления во внутреннем подмножестве (обычно это объявления сущностей), вам, скорее всего, придется хранить декларацию doctype в XML.

    Проблема, с которой сталкивается синтаксический анализатор XML, заключается в том, что вы не используетев декларации нет системного идентификатора.В декларации типа документа XML системный идентификатор требуется, если есть открытый идентификатор.В объявлении типа документа SGML это не требуется.

    Итог : если вам не нужен XML для анализа DTD / Schema или нет объявлений во внутреннем подмножестве, удалите объявление doctype.Если XML-код должен быть действительным, вам, по крайней мере, нужно добавить системный идентификатор.Не забудьте добавить инструкцию обработки <?xml ...?>.

  2. Элементы без конечных тегов

    Элементы <hardhyphen> и <hyphen>действительны SGML.DTD SGML позволяют вам указывать минимизацию тегов.Это означает, что вы можете указать, требуется ли конечный тег или нет.(Вы также можете сделать стартовый тег необязательным, но это ненормальный разговор.) В XML вы должны закрыть эти элементы (например, <hardhyphen/> или <hardhyphen></hardhyphen>)

    Лучше всего посмотреть на свойSGML DTD и посмотрите, какие элементы имеют дополнительные конечные теги.Минимизация тега указывается сразу после имени элемента в объявлении элемента.«-» означает, что тег обязателен.'O' (буква 'oh') означает, что тег является необязательным.Например, если вы видите <!ELEMENT hyphen - o (#PCDATA)>, это означает, что требуется начальный тег (-), а конечный тег необязательный (o).Если вы видите <!ELEMENT hyphen - - (#PCDATA)>, требуются как начальный, так и конечный теги.

    Нижняя строка : правильно закройте все элементы, у которых нет конечных тегов

  3. Инструкции обработки

    Инструкции обработки (PI) в SGML не имеют второго ?, когда они закрываются, как это делает XML.Вам нужно будет добавить второй ?.

    Пример SGML PI: <?asdf jkl>

    Пример XML PI: <?asdf jkl?>

  4. Включения / Исключения

    Возможно, вам не придется об этом беспокоиться, но в DTD SGML вы можете указать в объявлении элемента, что в любом месте внутри этого элемента разрешен другой элемент (илине положено).Это может быть проблемой, если ваш целевой XML должен анализировать DTD;XML DTD не допускает включения / исключения.

    Вот как может выглядеть включение:

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

    Это говорит о том, что revst или revendразрешены в любом месте chapter.Если бы объявление элемента имело -(revst|revend), это означало бы, что revst или revend не разрешено где-либо внутри chapter.

Надеюсь, что этопомогает.

1 голос
/ 20 ноября 2010

Да, используйте Нокогири .

Прокрутите немного на этой странице и скопируйте код в «Синопсис» в файл, скажем, xml-parser.rb. Затем, если вы работаете на Mac (Ruby уже установлен на Mac.), Из Terminal запустите gem install nokogiri, а затем запустите файл с: ruby xml-parser.rb.

Вы также можете набрать irb справа от терминала, а затем require 'nokogiri' и начать играть с API-интерфейсом nokogiri в режиме реального времени. Должен любить интерактивные Руби. :)

Если вы работаете в Windows, попробуйте этот Ruby Installer для Windows .

...