У меня есть некоторый 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();
}
Это работает, но имеет две проблемы:
- Это неэффективно, потому что весь документ будет проанализирован, даже если необходим только первый элемент.
- Что еще более важно, этот код иногда (очевидно, в зависимости от конфигурации брандмауэра) вызывает исключение 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)
Итак, мои вопросы:
- Очевидно, этот бит кода подключается к Интернету.Как я могу избежать этого?Помимо возникновения проблем с брандмауэрами, он также излишне медленен.
- Почему подключается к Интернету?Пожалуйста, помогите мне понять логику здесь, в этом не должно быть абсолютно никакой необходимости.
- Существует ли более эффективный способ определения пространства имен корневого элемента XML-документа?
Редактировать: вот ссылка на образец документа, который я пытаюсь проанализировать следующим образом: https://libsbgn.svn.sourceforge.net/svnroot/libsbgn/trunk/test-files/PD/adh.sbgn
Редактировать2: примечание относительно решения этой ошибки: На самом деле проблема была вызвана, потому чтобыл проанализирован неверный документ, вместо намеченного документа я анализировал документ XHMTML, который фактически ссылается на www.w3.org.Конечно, решение состоит в том, чтобы использовать правильный документ.Тем не менее, я нашел полезным добавить следующую строку:
xr.setEntityResolver(null);
Чтобы запретить ксеркам переходить через Интернет, когда это действительно совершенно не нужно.