Устойчивый к ошибкам синтаксический анализ XML в Scala

2

Я хотел бы иметь возможность анализировать XML, который не обязательно хорошо сформирован. Я бы искал нечеткий, а не строгий синтаксический анализатор, способный, например, восстанавливаться от сильно вложенных тегов. Я мог бы написать свой собственный, но стоит сначала спросить здесь.

Update:

То, что я пытаюсь сделать, это извлечь ссылки и другую информацию из HTML. В случае хорошо сформированного XML я могу использовать XML-интерфейс Scala. В случае плохо сформированного XML было бы неплохо каким-то образом преобразовать его в правильный XML (каким-то образом) и обработать его таким же образом, иначе мне пришлось бы иметь два совершенно разных набора функций для работы с документами.

Очевидно, потому что вход не очень хорошо сформирован, и я пытаюсь создать хорошо сформированное дерево, нужно было бы задействовать какую-то эвристику (например, когда вы видите <parent><child></parent>, вы сначала закрываете <child> и когда вы видите <child>, вы игнорируете его). Но, конечно, это не правильная грамматика, и поэтому нет правильного способа сделать это.

Теги:

8 ответов

7
Лучший ответ

То, что вы ищете, не будет XML-парсером. XML очень строг в отношении вложения, закрытия и т.д. Один из других ответов предлагает Tag Soup. Это хорошее предложение, хотя технически оно намного ближе к лексеру, чем к парсеру. Если все, что вы хотите от XML-ish-контента, является потоком событий без какой-либо проверки, то это почти тривиально, чтобы катить собственное решение. Просто пропустите вход, потребляя контент, который соответствует регулярным выражениям (это именно то, что делает Tag Soup).

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

<parent>
    <child>
    </parent>
</child>

Подумайте: какое дерево ожидало бы от этого? На самом деле нет разумного ответа на этот вопрос, и именно поэтому синтаксический анализатор не будет очень полезен.

Теперь, чтобы не сказать, что вы не можете использовать Tag Soup (или собственный ручной лексер) для создания какой-то древовидной структуры на основе этого ввода, но реализация будет очень хрупкой. С ориентированными на дерево форматами, такими как XML, у вас действительно нет выбора, кроме как быть строгим, иначе становится практически невозможным получить разумный результат (это часть того, почему браузеру так сложно работать с совместимостью).

  • 0
    Правда, наиболее близким совпадением для моей проблемы является тот тип вывода, который это дает. У меня есть идея о том, какие правила я бы использовал для создания дерева XML (я надеялся использовать XML API для запросов), но, конечно, это не было бы «правильным» удаленно. Я могу просто сделать это более прагматичным способом.
2

Взгляните на htmlcleaner. Я успешно использовал его для преобразования "HTML из дикой природы" в действительный XML.

2

Попробуйте синтаксический анализатор на объекте XHtml. Это гораздо более мягко, чем тот, что есть в XML.

1

Я согласен с ответами на то, что превращение недопустимого XML в "правильный" XML невозможно.

Почему бы вам просто не выполнять обычный текстовый поиск hrefs, если это все, что вам интересно? Одна из проблем будет связана с комментариями, но если XML недействителен, возможно, не удастся рассказать о том, что должно быть прокомментировано!

  • 0
    Причина, по которой я хотел этого, заключалась в том, чтобы использовать API-интерфейс Scala XML для тех правильно сформированных документов, которые я нахожу, и сначала попытаться исправить поврежденные. Я полагаю, просто относиться к нему как к строке.
  • 0
    Одна из причин , возможно , не хотите , чтобы сделать поиск текста, если вы только хотите , чтобы извлечь ссылки из a тегах , а не, например, link тег или DOCTYPE декларацию.
1

Я в основном согласен с ответом Даниэля Спиевака. Это просто еще один способ создать "ваш собственный парсер".

Пока я не знаю какого-либо специального решения Scala, вы можете попробовать использовать Woodstox, библиотеку Java, которая реализует StAX API. (Будучи API с четным основанием, я предполагаю, что он будет более терпимым к ошибкам, чем парсер DOM)

Существует также оболочка Scala вокруг Woodstox, называемая Frostbridge, разработанная тем же парнем, который создал Simple Build Tool для Scala.

У меня были смешанные мнения о Фростбридже, когда я это пробовал, но, возможно, он более подходит для ваших целей.

1

Попробуйте Tag Soup.

JTidy делает что-то подобное, но только для HTML.

0

Связанная тема (с моим решением) приведена ниже:

Scala и анализ html

0

Caucho имеет JAXP-совместимый XML-синтаксический анализатор, который немного более терпим, чем то, что вы обычно ожидаете. (Включая поддержку для работы с ссылками на ссылки на несуществующие символы, AFAIK.)

Найти JavaDoc для парсеров здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню