java 使用相对路径上的 DTD 模式解析 XML 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4726279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parsing an XML file with a DTD schema on a relative path
提问by User1
I have the following java code:
我有以下java代码:
DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc=db.parse(new File("/opt/myfile"));
And /opt/myfile
contains something like:
并/opt/myfile
包含以下内容:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE archive SYSTEM "../../schema/xml/schema.dtd"> ...
I get the following error:
我收到以下错误:
java.io.FileNotFoundException: /../schema/xml/schema.dtd (No such file or directory)
This is a large java framework that consumes an XML file produced elsewhere. I think the relative path is the problem. I don't think it will be acceptable to change the cwd before the JVM starts (the path comes from a config file that is read by the JVM itself) and I have not found a way to change the cwd while the JVM is running. How do I parse this XML file with the appropriate DTD?
这是一个大型 java 框架,它使用在别处生成的 XML 文件。我认为相对路径是问题所在。我认为在 JVM 启动之前更改 cwd 是不可接受的(路径来自 JVM 本身读取的配置文件),而且我还没有找到在 JVM 运行时更改 cwd 的方法。如何使用适当的 DTD 解析此 XML 文件?
回答by dogbane
You need to use a custom EntityResolverto tweak the path of the DTD so that it can be found. For example:
您需要使用自定义EntityResolver来调整 DTD 的路径,以便可以找到它。例如:
db.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.contains("schema.dtd")) {
return new InputSource(new FileReader("/path/to/schema.dtd"));
} else {
return null;
}
}
});
If schema.dtd
is on your classpath, you can just use getResourceAsStream
to load it, without specifying the full path:
如果schema.dtd
在您的类路径中,您可以使用getResourceAsStream
加载它,而无需指定完整路径:
return new InputSource(Foo.class.getResourceAsStream("schema.dtd"));
回答by Erel Segal-Halevi
You can also ignore the DTD altogether: http://marcels-javanotes.blogspot.com/2005/11/parsing-xml-file-without-having-access.html
您也可以完全忽略 DTD:http: //marcels-javanotes.blogspot.com/2005/11/parsing-xml-file-without-have-access.html
回答by Roman
I used the custom EntityResolver like the example above but it still searched the DTD file in another base directory. So I debuged it and then found out I need to change user.dir system property. So I added this line to my application initialization method and it works now.
我像上面的例子一样使用了自定义的 EntityResolver,但它仍然在另一个基本目录中搜索 DTD 文件。所以我调试了它,然后发现我需要更改 user.dir 系统属性。所以我将这一行添加到我的应用程序初始化方法中,现在它可以工作了。
System.setProperty("user.dir")
回答by Shubham Jain
Below code work for me, It ignore DTD
下面的代码对我有用,它忽略了 DTD
Imports:
进口:
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
Code :
代码 :
File fileName = new File("XML File Path");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
EntityResolver resolver = new EntityResolver () {
public InputSource resolveEntity (String publicId, String systemId) {
String empty = "";
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
System.out.println("resolveEntity:" + publicId + "|" + systemId);
return new InputSource(bais);
}
};
documentBuilder.setEntityResolver(resolver);
Document document = documentBuilder.parse(fileName);