【问题标题】:how to disable dtd at runtime in java's xpath?如何在运行时在 java 的 xpath 中禁用 dtd?
【发布时间】:2010-09-19 14:43:41
【问题描述】:

我在文件中找到了 dtd,但我无法删除它。当我尝试在 Java 中解析它时,我得到“由:java.net.SocketException:网络无法访问:连接”,因为它的远程 dtd。我可以以某种方式禁用 dtd 检查吗?

【问题讨论】:

    标签: java xpath dtd doctype


    【解决方案1】:

    您应该能够指定自己的 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);
        }
    }
    

    希望这会有所帮助...

    【讨论】:

    • 谢谢,这将我正在进行的一些单元测试减少了 7 倍。
    【解决方案2】:

    这对我有用:

     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();
      }
    

    【讨论】:

    • +1 - 这是最好的答案 - 但是只使用这一行就足够了:saxfac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    【解决方案3】:

    我以前遇到过这个问题。我通过下载和存储 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

    【讨论】:

    • 你好,当我们写 SYSTEM "filename.dtd" 时,windows 上的默认路径是什么 C:/windows/system32/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2020-08-18
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    相关资源
    最近更新 更多