使⽤JavaAPI通过DTD⽅式验证XML
摘要
本⽂记述了如何使⽤Java 8API 解析但不验证、按照XML⽂件头的DOCTYPE声明验证、使⽤本地⽂件验证XML的⽅法。本⽂不涉及如何读取、修改XML节点,以及创建XML⽂档的内容。
解析但不验证
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
l.parsers.DocumentBuilder;
l.parsers.DocumentBuilderFactory;
l.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
l.sax.SAXException;
public class XMLParser {
public static void main(String[] args) {
try {
String xmlToParse = "l";
DocumentBuilderFactory dbf =
// 默认DocumentBuilderFactory不创建
// 启⽤验证功能的DocumentBuilder
DocumentBuilder db = wDocumentBuilder();
Document myDoc = db.parse(xmlToParse);
} catch (ParseConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
使⽤XML⽂件头部声明的DOCTYPE验证
l.parsers.DocumentBuilderFactory;
l.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
l.sax.SAXException;
public class XMLParser {
public static void main(String[] args) {
try {
String xmlToParse = "l";
DocumentBuilderFactory dbf =
dbf.setValidating(true);  // 注意这⾥不同
DocumentBuilder db = wDocumentBuilder();
Document myDoc = db.parse(xmlToParse);
} catch (ParseConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
这时可能抛出IOException,原因通常是没有到XML所声明的DTD⽂件
如果XML声明的DTD在本地,可能会报FileNotFoundException。此时需要检查本地DTD的路径是否填写正确
否则可能报SocketException。此时需要检查⽹络是否畅通
然⽽此时即使XML不符合所声明DTD的定义,SAXException也可能不会被抛出,⽽仅仅是报错信息通过打印出来,同时会打印运⾏警告:“警告: 已启⽤验证, 但未设置 l.sax.ErrorHandler, 这可能不是预期结果。解析器将使⽤默认 ErrorHandler 来输出前0 个错误。请调⽤ ‘setErrorHandler’ ⽅法以解决此问题。”
这是因为没有设置ErrorHandler。如果希望SAXException在发⽣验证错误时被抛出,需要通过DocumentBuilder.setErrorHandler(ErrorHandler eh)⽅法进⾏设置。
重写上述代码如下:
l.parsers.DocumentBuilderFactory;
l.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
l.sax.ErrorHandler;  // 注意这⾥不同
l.sax.SAXException;
l.sax.SAXParseException;  // 注意这⾥不同
public class XMLParser {
public static void main(String[] args) {
try {
String xmlToParse = "l";
DocumentBuilderFactory dbf =
dbf.setValidating(true);
DocumentBuilder db = wDocumentBuilder();
db.setErrorHandler(new ErrorHandler() {
/*
* 定义了⼀个只要出⼀点解析错误就抛出异常的ErrorHandler。
* 读者可以以此为依据编写更精细化管理的ErrorHandler。
*/
@Override
public void error(SAXParseException exception)
throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception)
throws SAXException {
throw exception;
}
@Override
public void warning(SAXParseException exception)
throws SAXException {
throw exception;
}
});  // 注意这⾥不同
Document myDoc = db.parse(xmlToParse);
java xml是什么} catch (ParseConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
使⽤本地DTD⽂件验证
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
l.parsers.DocumentBuilder;
l.parsers.DocumentBuilderFactory;
l.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Document;
l.sax.ErrorHandler;
l.sax.EntityHandler;  // 注意这⾥不同
l.sax.InputSource;  // 注意这⾥不同
l.sax.SAXException;
l.sax.SAXParseException;
public class XMLParser {
public static void main(String[] args) {
try {
String xmlToParse = "l";
DocumentBuilderFactory dbf =
dbf.setValidating(true);
DocumentBuilder db = wDocumentBuilder();
db.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception)
throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception)
throws SAXException {
throw exception;
}
@Override
public void warning(SAXParseException exception)
throws SAXException {
throw exception;
}
});
db.setEntityResolver(new EntityResolver() {
/*
* 编写了根据PUBLIC域使⽤相应的本地dtd的EntityResolver;
* 读者也可以据此编写根据SYSTEM域使⽤相应dtd的EntityResolver;                * 或不管xml中声明成什么DOCTYPE,都使⽤同⼀份dtd进⾏验证,                * 此时resolveEntity⽅法体中仅包含
*    return new InputSource("a-fixed-dtd-path");
*/
@Override
public InputSource resolveEntity(String publicId,
String systemId) {
switch (publicId) {  // 此处仅为⽰意
case"URL-sample-1":
return new InputSource(
"local-dtd-path-for-url-sample-1");
case"URL-sample-2":
return new InputSource(
"local-dtd-path-for-url-sample-2");
default:
// 仍然按照DOCTYPE去解析,此时可能抛出IOException
return null;
}
});  // 注意这⾥不同
Document myDoc = db.parse(xmlToParse);
} catch (ParseConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。