代码之家  ›  专栏  ›  技术社区  ›  IAdapter

如何在Java的XPath中禁用运行时DTD?

  •  14
  • IAdapter  · 技术社区  · 16 年前

    文件里有DTD,我不能把它删除。当我试图在Java中解析它时,我会得到“Java.NET.SoCoCutExc:网络是不可达的:Connect”,因为它的远程DTD。我可以禁用DTD检查吗?

    3 回复  |  直到 12 年前
        1
  •  18
  •   Community CDub    8 年前

    您应该能够指定自己的EntityResolver,或者使用解析器的特定功能?见 here 对于某些方法。

    更完整的例子:

    <?xml version="1.0"?>
    <!DOCTYPE foo PUBLIC "//FOO//" "foo.dtd">
    <foo>
        <bar>Value</bar>
    </foo>
    

    和xpath用法:

    import java.io.File;
    import java.io.IOException;
    import java.io.StringReader;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathFactory;
    
    import org.w3c.dom.Document;
    import org.xml.sax.EntityResolver;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
    
            builder.setEntityResolver(new EntityResolver() {
    
                @Override
                public InputSource resolveEntity(String publicId, String systemId)
                        throws SAXException, IOException {
                    System.out.println("Ignoring " + publicId + ", " + systemId);
                    return new InputSource(new StringReader(""));
                }
            });
            Document document = builder.parse(new File("src/foo.xml"));
            XPathFactory xpathFactory = XPathFactory.newInstance();
            XPath xpath = xpathFactory.newXPath();
            String content = xpath.evaluate("/foo/bar/text()", document
                    .getDocumentElement());
            System.out.println(content);
        }
    }
    

    希望这有帮助…

        2
  •  14
  •   David    15 年前

    这对我很有用:

     SAXParserFactory saxfac = SAXParserFactory.newInstance();
      saxfac.setValidating(false);
      try {
        saxfac.setFeature("http://xml.org/sax/features/validation", false);
        saxfac.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
        saxfac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        saxfac.setFeature("http://xml.org/sax/features/external-general-entities", false);
        saxfac.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
      }
      catch (Exception e1) {
        e1.printStackTrace();
      }
    
        3
  •  2
  •   Owen    16 年前

    我以前有过这个问题。我通过下载和存储DTD的本地副本,然后根据本地副本进行验证,解决了这个问题。您需要编辑XML文件以指向本地副本。

    <!DOCTYPE root-element SYSTEM "filename">
    

    这里有更多信息: http://www.w3schools.com/dtd/dtd_intro.asp

    我认为您还可以在解析器中手动将某种validateOnParse属性设置为“false”。取决于您用来解析XML的库。

    更多信息在这里: http://www.w3schools.com/dtd/dtd_validation.asp