Adi*_*ram 2 java xml xsd saxparseexception
我有一个xsd文件和一个xml文件,我正在使用以下代码对xsd文件验证xml文件
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setAttribute(
"http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
factory.setAttribute(
"http://java.sun.com/xml/jaxp/properties/schemaSource",
new InputSource(new StringReader(xsd)));
Document doc = null;
try {
DocumentBuilder parser = factory.newDocumentBuilder();
MyErrorHandler errorHandler = new MyErrorHandler();
parser.setErrorHandler(errorHandler);
doc = parser.parse(new InputSource(new StringReader(xml)));
return true;
} catch (ParserConfigurationException e) {
System.out.println("Parser not configured: " + e.getMessage());
} catch (SAXException e) {
System.out.print("Parsing XML failed due to a "
+ e.getClass().getName() + ":");
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println("IOException thrown");
e.printStackTrace();
}
return false;
Run Code Online (Sandbox Code Playgroud)
MyErrorHanlder是
private static class MyErrorHandler implements ErrorHandler {
public void warning(SAXParseException spe) throws SAXException {
System.out.println("Warning: " + spe.getMessage() + " getColumnNumber is " + spe.getColumnNumber() + " getLineNumber " + spe.getLineNumber() + " getPublicId " + spe.getPublicId() + " getSystemId " + spe.getSystemId());
}
public void error(SAXParseException spe) throws SAXException {
System.out.println("Error: " + spe.getMessage() + " getColumnNumber is " + spe.getColumnNumber() + " getLineNumber " + spe.getLineNumber() + " getPublicId " + spe.getPublicId() + " getSystemId " + spe.getSystemId());
throw new SAXException("Error: " + spe.getMessage());
}
public void fatalError(SAXParseException spe) throws SAXException {
System.out.println("Fatal Error: " + spe.getMessage() + " getColumnNumber is " + spe.getColumnNumber() + " getLineNumber " + spe.getLineNumber() + " getPublicId " + spe.getPublicId() + " getSystemId " + spe.getSystemId());
throw new SAXException("Fatal Error: " + spe.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
当xml不符合xsd我得到一个异常..但是这个异常没有xsd元素的名称,因为这个错误发生了..消息看起来像
由于org.xml.sax.SAXException,解析XML失败:错误:cvc-minLength-valid:对于类型为"null"的minLength'1',值''with length ='0'不是facet-valid.
而不是打印xsd元素的名称,错误消息只有''.因此,我无法找到并向用户显示导致错误的确切元素.
我的xsd元素看起来像这样
<xs:element name="FullName_FirstName">
<xs:annotation>
<xs:appinfo>
<ie:label>First Name</ie:label>
<ie:html_element>0</ie:html_element>
</xs:appinfo>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
提前致谢
首先,一些建议.您不需要构建DOM文档来进行验证.这会导致大量内存开销,甚至可能耗尽大型输入XML文档.你可以使用一个SAXParser.如果您使用的是Java 1.5或更高版本,则甚至不需要.从该版本开始,Java SE中包含了一个XML验证API.检查包javax.xml.validation以获取更多信息.我们的想法是,您首先构建一个Schema对象,然后Validator从可用于进行验证的对象中获取一个对象.它接受任何Source输入实现.也可以给出验证器ErrorHandlers,因此您可以重复使用您的类.当然,实际上你可能需要一个DOM,但在这种情况下,最好还是创建一个Schema实例并将其注册到你的实例中DocumentBuilderFactory.
现在,针对实际问题.这并不容易,因为SAXParseException它没有为您提供太多的上下文信息.最好的办法是在ContentHandler某个地方连接并跟踪你所在的元素或其他位置信息.然后,您可以在需要时将其赋予错误处理程序.该类DefaultHandler或是DefaultHandler2将错误和内容处理相结合的便捷方式.您可以在org.xml.sax.ext包中找到这些类.
我已经在下面发布了一个测试.现在,我确实获得了两行输出而不是预期输出.如果这是因为我正在使用Schema,或者因为我没有抛出异常并继续处理,我不确定.第二行确实包含元素的名称,因此可能就足够了.您可以在错误上设置一些标志,而不是抛出异常并结束解析.
package jaxb.test;
import java.io.StringReader;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
public class ValidationTest {
public static void main(String[] args) throws Exception {
//Test XML and schema
final String xml = "<?xml version=\"1.0\"?><test><test2></test2></test>";
final String schemaString =
"<?xml version=\"1.0\"?>"
+ "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"unqualified\" attributeFormDefault=\"unqualified\">"
+ "<xsd:element name=\"test\" type=\"Test\"/>"
+ "<xsd:element name=\"test2\" type=\"Test2\"/>"
+ "<xsd:complexType name=\"Test\">"
+ "<xsd:sequence>"
+ "<xsd:element ref=\"test2\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>"
+ "</xsd:sequence>"
+ "</xsd:complexType>"
+ "<xsd:simpleType name=\"Test2\">"
+ "<xsd:restriction base=\"xsd:string\"><xsd:minLength value=\"1\"/></xsd:restriction>"
+ "</xsd:simpleType>"
+ "</xsd:schema>";
//Building a Schema instance
final Source schemaSource =
new StreamSource(new StringReader(schemaString));
final Schema schema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaSource);
//Creating a SAXParser for our input XML
//First the factory
final SAXParserFactory factory = SAXParserFactory.newInstance();
//Must be namespace aware to receive element names
factory.setNamespaceAware(true);
//Setting the Schema for validation
factory.setSchema(schema);
//Now the parser itself
final SAXParser parser = factory.newSAXParser();
//Creating an instance of our special handler
final MyContentHandler handler = new MyContentHandler();
//Parsing
parser.parse(new InputSource(new StringReader(xml)), handler);
}
private static class MyContentHandler extends DefaultHandler {
private String element = "";
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName != null && !localName.isEmpty())
element = localName;
else
element = qName;
}
@Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println(element + ": " + exception.getMessage());
}
@Override
public void error(SAXParseException exception) throws SAXException {
System.out.println(element + ": " + exception.getMessage());
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println(element + ": " + exception.getMessage());
}
public String getElement() {
return element;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这有点粗糙,但你可以从中做到这一点,以获得你需要的东西.
| 归档时间: |
|
| 查看次数: |
10561 次 |
| 最近记录: |