Получить пространство имен xml (без вызова UnknownHostException) - PullRequest
0 голосов
/ 11 августа 2011

У меня есть некоторый Java-код, который определяет пространство имен элемента корневого уровня документа XML с использованием SAX.Если пространство имен «http://sbgn.org/libsbgn/pd/0.1",», оно должно возвращать версию 1. Если пространство имен «http://sbgn.org/libsbgn/0.2",», версия должна быть 2. Таким образом, весь код выполняет чтение первого элемента и устанавливает переменную на основе пространства имен.Вот код:

private static class VersionHandler extends DefaultHandler
{
    private int version = -1;

    @Override
    public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException
    {
        if ("sbgn".equals (qName))
        {
            System.out.println (uri);
            if ("http://sbgn.org/libsbgn/0.2".equals(uri))
            {
                version = 2;
            } 
            else if ("http://sbgn.org/libsbgn/pd/0.1".equals(uri))
            {
                version = 1;
            } 
            else
            {
                version = -1;
            }
        }
    }

    public int getVersion() { return version; }
};

public static int getVersion(File file) throws SAXException, FileNotFoundException, IOException
{
    XMLReader xr;   
    xr = XMLReaderFactory.createXMLReader();

    VersionHandler versionHandler = new VersionHandler();

    xr.setContentHandler(versionHandler);
    xr.setErrorHandler(versionHandler);
    xr.parse(new InputSource(
        InputStreamToReader.inputStreamToReader(
            new FileInputStream (file))));

    return versionHandler.getVersion();
}   

Это работает, но имеет две проблемы:

  1. Это неэффективно, потому что весь документ будет проанализирован, даже если необходим только первый элемент.
  2. Что еще более важно, этот код иногда (очевидно, в зависимости от конфигурации брандмауэра) вызывает исключение UnknownHostException, например:
    java.net.UnknownHostException: www.w3.org 
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at sun.net.NetworkClient.doConnect(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown
    Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
    Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown
    Source)
    at
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown
    Source)
    at org.sbgn.SbgnVersionFinder.getVersion(SbgnVersionFinder.java:57)

Итак, мои вопросы:

  1. Очевидно, этот бит кода подключается к Интернету.Как я могу избежать этого?Помимо возникновения проблем с брандмауэрами, он также излишне медленен.
  2. Почему подключается к Интернету?Пожалуйста, помогите мне понять логику здесь, в этом не должно быть абсолютно никакой необходимости.
  3. Существует ли более эффективный способ определения пространства имен корневого элемента XML-документа?

Редактировать: вот ссылка на образец документа, который я пытаюсь проанализировать следующим образом: https://libsbgn.svn.sourceforge.net/svnroot/libsbgn/trunk/test-files/PD/adh.sbgn

Редактировать2: примечание относительно решения этой ошибки: На самом деле проблема была вызвана, потому чтобыл проанализирован неверный документ, вместо намеченного документа я анализировал документ XHMTML, который фактически ссылается на www.w3.org.Конечно, решение состоит в том, чтобы использовать правильный документ.Тем не менее, я нашел полезным добавить следующую строку:

 xr.setEntityResolver(null);

Чтобы запретить ксеркам переходить через Интернет, когда это действительно совершенно не нужно.

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Вероятно, он подключается к Интернету, потому что ваш документ ссылается на DTD или другой внешний объект на веб-сайте W3C. Ранее в этом году W3C прекратил обслуживание этих документов, поскольку они не могли обрабатывать трафик.

Вы можете решить проблему чтения всего документа, выбрасывая SAXException из одного из ваших обратных вызовов, как только вы увидите столько документа, сколько вам нужно. Убедитесь, что в коде, который вызывает метод XMLReader.parse (), можно отличить это исключение от исключений, генерируемых самим анализатором (например, вы можете создать подкласс SAXException: хотя не все анализаторы генерируют исходное исключение без изменений, и вам может потребоваться экспериментировать. )

2 голосов
/ 11 августа 2011

Полагаю, вам нужно установить распознаватель сущностей.См. Javadoc .Кроме того, эта статья представляется актуальной.

...