1

HTML 4.01 Doctype を宣言する xml ファイルを解析したいと考えています。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
[...]
</html>

ローカル dtd の読み込みに Stax と XMLResolver を使用しています

XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
xmlInputFactory.setXMLResolver(new LocalXmlResolver());
xmlOutputFactory = XMLOutputFactory.newInstance();
xmlOutputFactory.createXMLEventWriter(...)


private static final Map<String, String> DTDS = new HashMap<String, String>(){{
    // XHTML 1.0 DTDs
    put("-//W3C//DTD XHTML 1.0 Strict//EN", "xhtml1-strict.dtd");
    put("-//W3C//DTD XHTML 1.0 Transitional//EN", "xhtml1-transitional.dtd");
    put("-//W3C//DTD XHTML 1.0 Frameset//EN", "xhtml1-frameset.dtd");

    put("-//W3C//DTD HTML 4.01//EN", "strict.dtd");
    put("-//W3C//DTD HTML 4.01 Transitional//EN", "loose.dtd");
    put("-//W3C//DTD HTML 4.01 Frameset//EN", "frameset.dtd");
}};

private static final class LocalXmlResolver implements XMLResolver {

        @Override
        public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
            Object result = null;

            String path = XHTML_DTD_PATH + DTDS.get(publicID);

            if (StringUtils.isNotBlank(path)) {
                result = getClass().getClassLoader().getResourceAsStream(path);
            }
            return result;
        }
    }

( w3c Web サイト)から dtd を取得しました。しかし、以下のようなノード内のすべてのコメントを削除するには、このファイルを変更する必要がありました:

 <!ENTITY % ContentType "CDATA"
    -- media type, as per [RFC2045]
    --> 

 <!ENTITY % ContentType "CDATA">

しかし、これらの変更の後でも、まだこのエラーがあります:

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[184,11]
Message: The element type is required in the element type declaration.
    [...]
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[184,11]
Message: The element type is required in the element type declaration.
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:598)
    at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:83)

dtd ファイルの 184 行目は次のとおりです。

<!ELEMENT (%fontstyle;|%phrase;) - - (%inline;)* >

何か案が ?

ありがとう

4

1 に答える 1

2

HTML は SGML 言語であるため、SGML DTD があります。SGML の詳細については、http: //validator.w3.org/docs/sgml.htmlを参照してください。

SGML は XML とは少し異なるため、XML パーサーがそれを解析できないのも不思議ではありません。

主な例は次のとおりです。

エンティティー宣言内のコメント (2 つのハイフンで区切られている: --これはコメントです--) は、SGML DTD では許可されていますが、XML DTD では許可されていません。

違いの詳細については、http://www.w3.org/TR/NOTE-sgml-xml-971215#nullに従ってください。

それでも、独自の XMLResolver を作成して、特定の DTD の DTD 解析を無効にすることはできません。

xmlInput = XMLInputFactory.newInstance();
xmlInput.setXMLResolver(new XMLResolver() {
    @Override
    public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
        ...
        // Disable dtd validation
        if ("The public id you except".equals(publicId)) {
            return IOUtils.toInputStream("");
        }
        ...
    }
});

HTMLパーサーについては、 http://jtidy.sourceforge.net/またはhttp://jsoup.org/を解決策として検討してください

于 2013-10-07T15:23:54.213 に答える