java 引入本地dtd,java解析xml文件读取本地dtd或者忽略dtd

Java程序在解析xml文件时,如果xml文件中指定了dtd,在默认会从指定的url下载dtd文件,但是很多情况下如果网络连接不上,或者防火墙原因,dtd文件无法下载下来导致程序报连接超时异常,解析xml失败。有两种方法解决该类问题:

1.指定从本地读取dtd文件

若要解析的xml文件中有如下的dtd声明:。

publicId:被引用的外部实体的公共标识符,如果未提供,则为 null。

上述的dtd声明中publicId为-//OASIS//DTD DITA Concept//EN

systemId:被引用的外部实体的系统标识符。

上述的dtd声明中systemId为http://docs.oasis-open.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd

可以通过重新SAX的EntityResolver类的resolveEntity(StringpublicId,StringsystemId) throwsSAXException,IOException方法指定读取本地的dtd文件,该放在在XML解析器解析xml之前调用,用于加载指定的dtd文件:

/**

* Implementation of org.xml.sax.EntityResolver that loads

* entitities (for example dtd files) from the classpath.

*/

public class ClasspathEntityResolver

implements EntityResolver

{

public InputSource resolveEntity(String publicId, String systemId)

throws SAXException, IOException

{

if (systemId != null)

{

int index = systemId.lastIndexOf('/');

if (index != -1)

{

systemId = systemId.substring(index + 1);

}

systemId = "/" + systemId;

InputStream istr = Thread.currentThread().getContextClassLoader().getResourceAsStream(systemId);

if (istr != null)

{

return new InputSource(istr);

}

}

return null;

}

}

在SAX解析xml文件之前,指定使用自定义的ClasspathEntityResolver:

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser saxParser = spf.newSAXParser();

xmlReader = saxParser.getXMLReader();

xmlReader.setEntityResolver(new ClasspathEntityResolver());

xmlReader.setContentHandler(handler);

try {

xmlReader.parse(new InputSource(inputFilePath));

} catch (Exception e) {

e.printStackTrace();

}

注意:

经常测试发现,这种方法只对SYSTEM(本地dtd)有效,如:

但是对于PUBLIC(外部dtd)不起作用,如:

PUBLIC方式的dtd依然从外部下载dtd,只能通过第二种方式忽略dtd校验。

2.解析xml文件时彻底忽略dtd:

SAX解析器可以通过指定http://apache.org/xml/features/nonvalidating/load-external-dtd属性来确定是否忽略dtd,例子如下:

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser saxParser = spf.newSAXParser();

xmlReader = saxParser.getXMLReader();

xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

xmlReader.setContentHandler(handler);

try {

xmlReader.parse(new InputSource(inputFilePath));

} catch (Exception e) {

e.printStackTrace();

}

这样指定之后,解析xml文件时,不再进行dtd校验。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值