Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java根据本地DTD文件验证XML文件_Java_Xml_Validation_Dtd - Fatal编程技术网

使用Java根据本地DTD文件验证XML文件

使用Java根据本地DTD文件验证XML文件,java,xml,validation,dtd,Java,Xml,Validation,Dtd,如何根据本地存储为文件的DTD验证XML文件?XML文件没有任何DOCTYPE声明(或者可能有一个应该被覆盖的DOCTYPE声明)。我看了一下,但除了他们正在使用.NET之外,我怀疑这是一个好的解决方案 欢迎任何意见 您必须实现EntityResolver,签出。在理想情况下,您可以使用。大概是这样的: SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.XML_DTD_NS_URI); Schema

如何根据本地存储为文件的DTD验证XML文件?XML文件没有任何DOCTYPE声明(或者可能有一个应该被覆盖的DOCTYPE声明)。我看了一下,但除了他们正在使用.NET之外,我怀疑这是一个好的解决方案


欢迎任何意见

您必须实现
EntityResolver
,签出。

在理想情况下,您可以使用。大概是这样的:

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实现(至少从Java6开始)不支持从DTD创建模式实例。您可能能够追踪到第三方实现

最好的办法可能是在使用其他机制进行解析之前修改文档以包含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声明


此事件读取器可以执行以下操作:

  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
XMLEventFactory eventFactory=XMLEventFactory.newInstance();
XMLEvent dtd=eventFactory
.createDTD(“”);
XMLInputFactory inFactory=XMLInputFactory.newInstance();
XMLOutputFactory outFactory=XMLOutputFactory.newInstance();
XMLEventReader=inFactory
.createXMLEventReader(新StreamSource(
“xmlValidate.xml”);
读卡器=新的dtd替换器(读卡器,dtd);
XMLEventWriter writer=outFactory.createXMLEventWriter(System.out);
writer.add(reader);
writer.flush();
//TODO错误和正确的流处理
请注意,XMLEventReader可能会形成执行验证的其他转换机制的源



如果您有这个选项,那么使用W3模式进行验证会容易得多。

我非常肯定前面提到的东西会起作用


谢谢您的帮助,但是如果没有指定DOCTYPE呢 全部的在这种情况下,整体解决方案不会帮助我,是吗?- 西蒙2009年7月8日6:34


@Bluegene:如果没有DOCTYPE,您将根据什么进行验证J-16 SDiZ 2009年7月8日7:12


反对我自己的DTD。我只是想确认我收到的XML 符合我的DTD,而不仅仅是发件人指定的任何DTD西蒙·朱尔 8点09分23点09分


如果问题是您希望根据dtd而不是作者对其进行验证,那么您应该确保有明确的文档详细说明doctype,以及xml文件中必须包含的内容

谢谢您的帮助,但是如果根本没有指定doctype怎么办?在这种情况下,EntityResolver不会帮助我,是吗?@Bluegene:如果没有DOCTYPE,你在验证什么?验证我自己的DTD。我只是想确保我收到的XML符合我的DTD,而不仅仅是发件人指定的任何DTD。非常感谢您的详细回答,这对我帮助很大。我将研究如何将DTD转换为W3模式,因为我可以使用Sun的验证器。我的XML文件没有任何DOCTYPE声明。我在Android中使用SAXParser解析文件。我自己生成的DTD。在SAX解析中,如何使用DTD验证XML文件?@Khushbu-如果您提出一个新问题会更好。我已经提出了问题,但没有得到正确的答案。如果丢弃的DTD系统id引用了不存在的文件,则会抛出WstxParsingException/FileNotFoundException。在inFactory实例化后添加
inFactory.setProperty(XMLInputFactory.SUPPORT\u DTD,false)