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

16

我的文件中有dtd,但我无法删除它。当我尝试在Java中解析它时,我会收到“Caused by: java.net.SocketException: Network is unreachable: connect”错误,因为它是远程dtd。我能否以某种方式禁用dtd检查?

3个回答

20

您应该能够指定自己的EntityResolver,或使用解析器的特定功能。参见这里,了解一些方法。

一个更完整的例子:

<?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倍。 - Scott Markwell

16
这对我有效:

这对我有效:

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

5
+1 - 这是这里最好的答案 - 然而仅使用这行代码就足够了:saxfac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - Denys Kniazhev-Support Ukraine

2

我曾经遇到过这个问题,解决方法是下载并存储DTD的本地副本,然后根据本地副本进行验证。您需要编辑XML文件以指向本地副本。

<!DOCTYPE root-element SYSTEM "filename">

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

我认为你也可以在解析XML时手动将某种验证属性设置为“false”。这取决于你用来解析XML的库。

更多信息请参见:http://www.w3schools.com/dtd/dtd_validation.asp


你好,当我们在Windows上写SYSTEM "filename.dtd"时,默认路径是C:/windows/system32/吗? - Abubakar Riaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接