如何根據本地存儲爲文件的DTD驗證XML文件? XML文件沒有任何DOCTYPE聲明(或者可能有一個應該被覆蓋)。我看了一下this thread,但除了他們使用.NET的事實之外,我懷疑這是一個很好的解決方案。使用Java根據本地DTD文件驗證XML文件
任何輸入讚賞!
如何根據本地存儲爲文件的DTD驗證XML文件? XML文件沒有任何DOCTYPE聲明(或者可能有一個應該被覆蓋)。我看了一下this thread,但除了他們使用.NET的事實之外,我懷疑這是一個很好的解決方案。使用Java根據本地DTD文件驗證XML文件
任何輸入讚賞!
在理想的世界中,您可以使用Validator進行驗證。事情是這樣的:
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實現(至少,如Java 6)不包括從DTD創建Schema實例的支持。您可能能夠追蹤第三方實施。
最好的辦法可能是在使用其他一些機制解析之前,將文檔改爲包含DTD。
可以使用transformer插入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聲明,並丟棄任何從舊文件。
演示用法:
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的可以構成爲執行驗證一些其他的轉化機制的來源。
如果您有該選項,使用W3模式進行驗證會容易得多。
您必須實施EntityResolver
,結帳this example。
即時通訊相當肯定,如果沒有DOCTYPE已在 全部被指定的東西,上述將工作..
感謝您的幫助,但什麼?在這種情況下EntityResolver不會幫助我,是嗎? - Simon Simon 09年8月8日在6:34
@Bluegene:什麼是驗證,如果沒有DOCTYPE? - J-16 SDiZ 09年7月8日7:12
對我自己的DTD。我只想確保我收到的XML 符合我的DTD,而不僅僅是發件人指定的任何DTD。 - 西蒙月 8 '09在23:09
如果問題是你希望它針對您的DTD進行驗證,而不是作家,你應該確保有清晰的文檔,詳細文檔類型,以及哪些必須在xml文件中
感謝您的幫助,但如果沒有指定DOCTYPE,該怎麼辦?在這種情況下EntityResolver不會幫助我,是嗎? – Simon 2009-07-08 06:34:19
@Bluegene:如果沒有DOCTYPE,你在驗證什麼? – 2009-07-08 07:12:36