2009-10-02 5 views
2

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

Update:

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

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

ответ

7

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

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

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

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

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

+0

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

1

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

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

2

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

1

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

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

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

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

1

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

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

+0

Причина, по которой я хотел, это использовать XML-интерфейс Scala для этих хорошо сформированных документов, которые я нахожу, и сначала попытаться исправить их. Я предполагаю, что просто рассматриваю его как строку. – Joe

+0

Одна из причин, по которой вы, возможно, не хотите выполнять текстовый поиск, - это только вы хотите извлечь ссылки из тегов 'a', а не, например, теги' link' или 'DOCTYPE'. –

0

У Caucho есть JSXP-совместимый синтаксический анализатор XML, который немного более терпим, чем то, что вы обычно ожидаете. (. В том числе и поддержку работы с беглых ссылок мнемоники, AFAIK)

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

2

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