使用Javavalidation本地DTD文件的XML文件
如何根据本地存储为文件的DTDvalidationXML文件? XML文件没有任何DOCTYPE声明(或者可能有一个应该被重写)。 我看看这个线程,但除了他们使用.NET的事实,我怀疑这是一个很好的解决scheme。
任何input赞赏!
在理想的世界中,您将能够使用validation器进行validation 。 像这样的东西:
SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.XML_DTD_NS_URI); Schema schema = schemaFactory.newSchema(new File( "xmlValidate.dtd")); Validator validator = schema.newValidator(); validator.validate(new StreamSource("xmlValidate.xml"));
不幸的是,Sun实现(至less从Java 6开始)不包括从DTD创buildSchema实例的支持。 您可能能够追踪第三方的实施。
您最好的select可能是在使用其他机制进行parsing之前,将文档更改为包含DTD。
你可以使用一个转换器来插入一个DTD声明:
TransformerFactory tf = TransformerFactory .newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty( OutputKeys.DOCTYPE_SYSTEM, "xmlValidate.dtd"); transformer.transform(new StreamSource( "xmlValidate.xml"), new StreamResult(System.out));
…但是这似乎并没有取代现有的DTD声明。
这个StAX事件阅读器可以完成这项工作:
public static class DTDReplacer extends EventReaderDelegate { private final XMLEvent dtd; private boolean sendDtd = false; public DTDReplacer(XMLEventReader reader, XMLEvent dtd) { super(reader); if (dtd.getEventType() != XMLEvent.DTD) { throw new IllegalArgumentException("" + dtd); } this.dtd = dtd; } @Override public XMLEvent nextEvent() throws XMLStreamException { if (sendDtd) { sendDtd = false; return dtd; } XMLEvent evt = super.nextEvent(); if (evt.getEventType() == XMLEvent.START_DOCUMENT) { sendDtd = true; } else if (evt.getEventType() == XMLEvent.DTD) { // discard old DTD return super.nextEvent(); } return evt; } }
它将在文档启动后立即发送一个给定的DTD声明,并丢弃旧文档中的任何DTD声明。
演示用法:
XMLEventFactory eventFactory = XMLEventFactory.newInstance(); XMLEvent dtd = eventFactory .createDTD("<!DOCTYPE Employee SYSTEM \"xmlValidate.dtd\">"); XMLInputFactory inFactory = XMLInputFactory.newInstance(); XMLOutputFactory outFactory = XMLOutputFactory.newInstance(); XMLEventReader reader = inFactory .createXMLEventReader(new StreamSource( "xmlValidate.xml")); reader = new DTDReplacer(reader, dtd); XMLEventWriter writer = outFactory.createXMLEventWriter(System.out); writer.add(reader); writer.flush(); // TODO error and proper stream handling
请注意,XMLEventReader可以形成执行validation的其他一些转换机制的源代码。
如果你有这个选项,使用W3模式validation会容易得多。
我敢肯定,上述的东西将工作..
感谢您的帮助,但是如果没有指定DOCTYPE呢? 在这种情况下EntityResolver不会帮助我,是吗? – – 蒙古09年7月8日在6:34
@Bluegene:如果没有DOCTYPE,你在validation什么? – – 16 SDiZ 09年7月8日在7:12
违反我自己的DTD。 我只是想确保我收到的XML符合我的DTD,而不仅仅是发件人指定的任何DTD。 – 西蒙7年7月8日在23:09
如果问题是你想要它对你的dtd而不是作者进行validation,你应该确保有明确的文档,详细的文档types,什么必须在xml文件
你必须实现EntityResolver
,检查这个例子 。