Java - синтаксический анализатор SAX в документе XHTML

Я пытаюсь написать синтаксический анализатор SAX для документа XHTML, который я загружаю из Интернета. Сначала у меня возникла проблема с объявлением doctype (отсюда я узнал, что это произошло из-за того, что W3C намеренно заблокировал доступ к DTD), но я исправил это с помощью:

XMLReader reader = parser.getXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);

Однако сейчас я испытываю вторую проблему. Анализатор SAX выдает исключение, когда достигает некоторого Javascript, встроенного в документ XHTML:

    <script type="text/javascript" language="JavaScript">
function checkForm() {
answer = true;
if (siw && siw.selectingSomething)
    answer = false;
    return answer;
}//
</script>

В частности, синтаксический анализатор выдает ошибку, как только достигает &&, поскольку он ожидает ссылку на сущность. Точное исключение:

`org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:391)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1390)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(XMLDocumentFragmentScannerImpl.java:1814)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3000)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:624)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:486)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:810)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:740)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:110)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1208)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:525)
at MLIAParser.readPage(MLIAParser.java:55)
at MLIAParser.main(MLIAParser.java:75)`

Я подозреваю (но я не знаю), что если бы я не отключил DTD, я бы не получил эту ошибку. Итак, как я могу избежать ошибки DTD и избежать ошибки ссылки на сущность?

Ура,

Пит

3 ответа

Решение

(X)HTML, который вы пытаетесь проанализировать, не является допустимым XML (иначе вы не получили бы ошибку синтаксического анализа SAX). И двойной амперсанд (&&") подтверждает это. Это означает, что сам по себе вы не можете использовать обычный синтаксический анализатор XML для разбора документа.

Есть инструменты, которые вы можете использовать, такие как TagSoup, которые будут генерировать правильные события SAX (вы можете использовать тот же код синтаксического анализа SAX/XML, как и раньше), но TagSoup позаботится о том, чтобы сопоставить плохо сформированные события HTML с правильным SAX/XML события.

Я думаю, что вы должны поместить содержимое сценария в раздел CDATA, например, http://www.w3schools.com/TAGS/tag_script.asp приводит следующий пример:

<script type="text/javascript"><![CDATA[
document.write("Hello World!")
//]]></script>

NekoHTML, вероятно, исправит это и для вас, вы используете его как XMLReader.

Если вы используете фильтр SAX, вы также можете вставить события CDATA после того, как встретите startElement для