Определение, является ли лента Atom или RSS - PullRequest
5 голосов
/ 29 сентября 2011

Я пытаюсь определить, является ли данный канал на основе Atom или RSS.

Вот мой код:

public boolean isRSS(String URL) throws ParserConfigurationException, SAXException, IOException{
        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        Document doc = builder
                .parse(URL);
        return doc.getDocumentElement().getNodeName().equalsIgnoreCase() == "rss";
    }

Есть ли лучший способ сделать это? было бы лучше, если бы вместо этого я использовал SAX Parser?

Ответы [ 3 ]

3 голосов
/ 02 октября 2011

Обнюхивание контента - один из методов. Но обратите внимание, что Atom использует пространства имен, и вы создаете парсер, не поддерживающий пространство имен.

public boolean isAtom(String URL) throws ParserConfigurationException, SAXException, IOException{
    DocumentBuilderFactory f = DocumentBuilderFActory.newInstance();
    f.setNamespaceAware(true);
    DocumentBuilder builder = f.newInstance().newDocumentBuilder();
    Document doc = builder.parse(URL);
    Element e = doc.getDocumentElement(); 
    return e.getLocalName().equals("feed") && 
            e.getNamespaceURI().equals("http://www.w3.org/2005/Atom");
}

Обратите внимание, что вы не можете сравнивать с помощью equalsIgnorCase (), поскольку имена элементов XML чувствительны к регистру.

Другой метод заключается в реакции на заголовок Content-Type, если он доступен в HTTP-запросе GET. Тип контента для ATOM будет application/atom+xml, а для RSS application/rss+xml. Однако я подозреваю, что не всем RSS-каналам можно доверять, чтобы корректно установить этот заголовок.

Третий вариант - посмотреть суффикс URL, например, .atom и .rss.

Последние два метода легко настраиваются, если вы используете Spring или JAX-RS

3 голосов
/ 02 октября 2011

Корневой элемент - это самый простой способ определить тип канала.

Для разных парсеров существуют разные способы получения корневого элемента.Ни один не уступает другому.Было написано достаточно о StAX против SAX против DOM и т. Д., Которые могут быть использованы в качестве основы для конкретного решения.

В ваших первых двух строках кода нет ничего плохого:

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(URL);

В вашем операторе возврата вы ошибаетесь при сравнении строк Java.

Когда вы используете оператор сравнения == со строками, он сравнивает ссылки, а не значения (т.е. вы проверяете, являются ли оба объекта одним и тем же объектом).).Вы должны использовать метод equals() здесь.Просто чтобы быть уверенным, я бы порекомендовал использовать equalsIgnoreCase():

return doc.getDocumentElement().getNodeName().equalsIgnoreCase("rss");

Подсказка: если вы проверяете «rss» вместо «feed» (как для Atom) в вашем isRss() методе, который вы не используетенужно использовать троичный оператор.

2 голосов
/ 03 октября 2011

Вы можете использовать синтаксический анализатор StAX, чтобы избежать анализа всего XML-документа в памяти:

public boolean isAtom(String url) throws ParserConfigurationException, SAXException, IOException{
    XMLInputFactory xif = XMLInputFactory.newFactory();
    XMLStreamReader xsr = xif.createXMLStreamReader(new URL(url).openConnection());
    xsr.nextTag();  // Advance to root element
    return xsr.getLocalName().equals("feed") && 
            xsr.getNamespaceURI().equals("http://www.w3.org/2005/Atom");
}
...