Я хотел бы иметь возможность анализировать XML, который не обязательно хорошо сформирован. Я бы искал нечеткий, а не строгий синтаксический анализатор, способный, например, восстанавливаться от сильно вложенных тегов. Я мог бы написать свой собственный, но стоит сначала спросить здесь.
Update:
То, что я пытаюсь сделать, это извлечь ссылки и другую информацию из HTML. В случае хорошо сформированного XML я могу использовать XML-интерфейс Scala. В случае плохо сформированного XML было бы неплохо каким-то образом преобразовать его в правильный XML (каким-то образом) и обработать его таким же образом, иначе мне пришлось бы иметь два совершенно разных набора функций для работы с документами.
Очевидно, потому что вход не очень хорошо сформирован, и я пытаюсь создать хорошо сформированное дерево, нужно было бы задействовать какую-то эвристику (например, когда вы видите <parent><child></parent>
, вы сначала закрываете <child>
и когда вы видите <child>
, вы игнорируете его). Но, конечно, это не правильная грамматика, и поэтому нет правильного способа сделать это.
То, что вы ищете, не будет XML-парсером. XML очень строг в отношении вложения, закрытия и т.д. Один из других ответов предлагает Tag Soup. Это хорошее предложение, хотя технически оно намного ближе к лексеру, чем к парсеру. Если все, что вы хотите от XML-ish-контента, является потоком событий без какой-либо проверки, то это почти тривиально, чтобы катить собственное решение. Просто пропустите вход, потребляя контент, который соответствует регулярным выражениям (это именно то, что делает Tag Soup).
Проблема заключается в том, что лексер не сможет предоставить вам много функций, которые вы хотите от парсера (например, создание древовидного представления ввода). Вы должны реализовать эту логику самостоятельно, потому что нет никакого способа, чтобы такой "мягкий" парсер мог определить, как обрабатывать такие случаи, как:
<parent>
<child>
</parent>
</child>
Подумайте: какое дерево ожидало бы от этого? На самом деле нет разумного ответа на этот вопрос, и именно поэтому синтаксический анализатор не будет очень полезен.
Теперь, чтобы не сказать, что вы не можете использовать Tag Soup (или собственный ручной лексер) для создания какой-то древовидной структуры на основе этого ввода, но реализация будет очень хрупкой. С ориентированными на дерево форматами, такими как XML, у вас действительно нет выбора, кроме как быть строгим, иначе становится практически невозможным получить разумный результат (это часть того, почему браузеру так сложно работать с совместимостью).
Взгляните на htmlcleaner. Я успешно использовал его для преобразования "HTML из дикой природы" в действительный XML.
Попробуйте синтаксический анализатор на объекте XHtml. Это гораздо более мягко, чем тот, что есть в XML.
Я согласен с ответами на то, что превращение недопустимого XML в "правильный" XML невозможно.
Почему бы вам просто не выполнять обычный текстовый поиск hrefs, если это все, что вам интересно? Одна из проблем будет связана с комментариями, но если XML недействителен, возможно, не удастся рассказать о том, что должно быть прокомментировано!
a
тегах , а не, например, link
тег или DOCTYPE
декларацию.
Я в основном согласен с ответом Даниэля Спиевака. Это просто еще один способ создать "ваш собственный парсер".
Пока я не знаю какого-либо специального решения Scala, вы можете попробовать использовать Woodstox, библиотеку Java, которая реализует StAX API. (Будучи API с четным основанием, я предполагаю, что он будет более терпимым к ошибкам, чем парсер DOM)
Существует также оболочка Scala вокруг Woodstox, называемая Frostbridge, разработанная тем же парнем, который создал Simple Build Tool для Scala.
У меня были смешанные мнения о Фростбридже, когда я это пробовал, но, возможно, он более подходит для ваших целей.
Связанная тема (с моим решением) приведена ниже:
Caucho имеет JAXP-совместимый XML-синтаксический анализатор, который немного более терпим, чем то, что вы обычно ожидаете. (Включая поддержку для работы с ссылками на ссылки на несуществующие символы, AFAIK.)
Найти JavaDoc для парсеров здесь