Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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文件?_Java_File_Parsing_Dtd - Fatal编程技术网

如何在Java中解析和分析DTD文件?

如何在Java中解析和分析DTD文件?,java,file,parsing,dtd,Java,File,Parsing,Dtd,我想用Java实现一个程序,以便将DTD文件作为输入 并基于DTD输出一个XML实例文件 这意味着我必须在Java中解析和分析DTD文件。 在线是否有定义分析方法的API DTD文件中的结构和元素 很遗憾,目前还没有用于读取/操作/写入DTD或XML模式的标准API或数据模型。最好的选择是寻找一个解析器,它为此提供了一个自定义API,或者只是将模式作为XML文档进行操作,并为其构建自己的数据模型 生成“基于DTD的XML实例文件”通常是一个定义很差的问题。对于任何给定的DTD,都有太多可能的文档

我想用Java实现一个程序,以便将DTD文件作为输入 并基于DTD输出一个XML实例文件

这意味着我必须在Java中解析和分析DTD文件。 在线是否有定义分析方法的API DTD文件中的结构和元素


很遗憾,目前还没有用于读取/操作/写入DTD或XML模式的标准API或数据模型。最好的选择是寻找一个解析器,它为此提供了一个自定义API,或者只是将模式作为XML文档进行操作,并为其构建自己的数据模型


生成“基于DTD的XML实例文件”通常是一个定义很差的问题。对于任何给定的DTD,都有太多可能的文档,这没有考虑到您可能希望数据内容也具有语义意义这一事实。使用XML模式可以做得更好一些,但即使这样,生成有效文档也只是生成正确文档的冰山一角。可以编写编辑工具来帮助用户生成格式良好的文档,但即使这样也可能会很混乱,因为两个有效文档之间最简单的编辑路径可能是通过无效文档。已经编写了一些工具来实现这一点,但它们没有得到广泛的应用,因为在大多数情况下,当您需要那么多帮助时,您需要全力以赴地编写一个完全了解文档语义的编辑器,包括DTD或模式无法表达的内容。

解析DTD的肮脏解决方案是滥用Xerces内部结构。您可以使用它作为一个起点来完成一些可以接受的事情,因为它在最近的JRE中已经可用,源代码可用(使用JDK或来自Apache),并且可以根据您的喜好进行修改(Apache许可证)。请注意,对于具有外部实体等的真实DTD,必须使用适配器(例如setEntityResolver/Feature/Property)配置XMLDTDLoader

这里有一些独立的代码可以试用(对于我来说,它似乎可以在OpenJDK 1.7.0和Oracle JDK 1.8.0上运行):

import org.xml.sax.InputSource;
导入com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
导入com.sun.org.apache.xerces.internal.impl.dtd.xmldtloader;
导入com.sun.org.apache.xerces.internal.util.SAXInputSource;
导入com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
公共类So26391485{
公共静态void main(字符串[]args)引发异常{
//最小示例DTD
StringWriter sw=新的StringWriter();
sw.写(“”);
sw.写(“”);
sw.写入(“]>”;
//读取DTD
InputStream dtdStream=新的ByteArrayInputStream(sw.toString().getBytes());
//InputStream dtdStream=So26391485.class.getResourceAsStream(“your.dtd”);
扫描仪=新扫描仪(dtdStream);
字符串dtdText=scanner.useDelimiter(“\\z”).next();
scanner.close();
//脏:使用Xerces内部构件解析DTD
Pattern dtdPattern=Pattern.compile(“^\\s*\\s*$”,Pattern.DOTALL);
Matcher m=dtdPattern.Matcher(dtdText);
如果(m.matches()){
字符串docType=m.group(1);
InputSource is=新的InputSource(新的StringReader(m.group(2));
XMLInputSource=新的SAXInputSource(is);
XMLDTDLoader d=新的XMLDTDLoader();
DTDGrammar g=(DTDGrammar)d.loadGrammar(源代码);
g、 打印元素();
}
}
}
(我不得不切掉DOCTYPE声明,因为我没有设法让Xerces按原样读取DTD。毕竟XMLDTDLoader并不打算这样使用…)

另一个选项是在模式编译器中使用的。它有一个好看的
com.sun.xml.dtdparser.dtdparser.parse(InputSource)
方法。我找不到任何这样的例子,但用法可能是:

// Gets the DTD events
DTDEventListener listener = ...;
// Instantiate the parser
DTDParser parser = new DTDParser();
// Set the nandler
parser.setDtdHandler(reader);
// Parse your DTD source
parser. parse(...);
然而,我首先要尝试Xerces(见另一个答案),因为这个DTD解析器似乎已经很旧了。我想这甚至是我在很久以前就把它变了

一般来说,基于DTD或XML模式生成示例XML文件的任务并不容易,记得这是2000年左右的一个博士级研究课题。我找不到链接,但如果我没有弄错的话,IBM有一篇非常好的研究论文


现在,我不再以DTD为基础,而是以XML模式为基础。

这里有一个有用的链接。好的,谢谢你的链接,但是在我的例子中,开头没有给出XML文件。我只有一个DTD文件,必须基于DTD文件生成一个XML文件。在您发布给我的链接中,用户在开始时已经有一个DTD和一个XML文件,因此我担心这篇文章对我没有帮助,因为用户希望根据给定的DTD文件再次验证给定的XML文件。另请参见:“不幸的是,没有用于读取/操作/写入DTD或XML模式的标准API或数据模型。”取决于你所谓的“标准”。没有
javax.*
API,但Xerces或XSOM是相当标准的。有特定于解析器的API。据我所知,没有任何东西是独立于解析器的,更不用说独立于语言了。(我们讨论了向DOM中添加此功能,但它遇到了DTD和模式之间已知不兼容的问题。)我不确定“特定于解析器”是什么意思。XSOM专门用于处理XML模式,并且有一个非常好的API。还有MSV(多模式验证器),我想,也是由Kohsuke编写的,现在已经非常古老了。JAXBXJC支持相当多的XML“模式”语言,如XMLSchema、DTD、RelaxNG,因此它们确实有用于此的内部表示模型。当然你是对的,没有统一的API,但我认为有很多值得使用的工具;您必须致力于特定工具的特定实现。这是不可取的,但哦,好吧。
// Gets the DTD events
DTDEventListener listener = ...;
// Instantiate the parser
DTDParser parser = new DTDParser();
// Set the nandler
parser.setDtdHandler(reader);
// Parse your DTD source
parser. parse(...);