我使用的是PTC ARBECTURE编辑器,它最初是在20世纪80年代末的前XML(SGML)日编写的。
组织.custommonkey.xmlunit
以区分XML文件。
diff工具无法解析文件所需的文件(在Windows上),这些文件使用分号分隔的绝对路径列表指向其查找的各个目录文件位置。
catalog
和/或
catalog.xml
文件夹。这些可以使用
CATALOG
指令。有使用
PUBLIC
映射到相对于特定目录文件的路径的标识符。
我正在使用这个目录信息分析XML,它可能包含文件实体和XML包含。
对于某些用例,我可以设置验证
false
这是可行的(假设这两个文件是有效的是合理的),但是对于某些文件,我必须读取目录信息来解析XML中的文件实体。
我可以要求用户提供到其顶级目录位置的绝对路径列表。但是,我很难选择一个解析器并将其集成到我的代码中。
我使用Java 1.8,但不介意去10,如果这有助于/简化。看起来9有一些简单的支持
javax.xml.catalog目录
但不是1.8或10。
如果这很重要,我可以提供我的解析代码,但我不会停留在任何一个解析器上。
我的代码在下面。我从
LSParser
到
DocumentBuilder
为了
setValidating(false)
。
以下是我希望能够使用的其中一个文件的一些摘录:
<?xml version="1.0" encoding="UTF-8"?>
<!--Arbortext, Inc., 1988-2016, v.4002-->
<!DOCTYPE Composer PUBLIC "-//Arbortext//DTD Composer 1.0//EN"
"../doctypes/composer/composer.dtd" [
<!ENTITY % stock PUBLIC "-//Arbortext//DTD Fragment - ATI Stock filter list//EN" "../composer/stock.ent">
%stock;
]>
<?Pub Inc?>
<Composer>
<Label>Compose to PDF</Label>
. . .
<Resource>
<Label></Label>
<Documentation></Documentation>&epicGenerator;
&fileSerializer;
&serverProfiler;
&clientProfiler;
&xslTransformer;
&epicSerializer;
&switch;
&errorHandler;
&namespaceFixer;
&atiEventConverter;
&foPropagator;
&extensionHandler;
&ditaPostProcessor;
&ditaStyledElementsTranslator;
&atictFilter;
&applicabilityFilter;
</Resource>
下面是我需要参考的目录文件中的几行:
PUBLIC "-//Arbortext//ENTITIES SAX Event Upstream Loop//EN" "upstreamLoop.ent"
PUBLIC "-//Arbortext//ENTITIES keyRef Resolver//EN" "keyRefResolver.ent"
PUBLIC "-//Arbortext//ENTITIES ATI Change Tracking Filter 1.0//EN" "atictFilter.ent"
PUBLIC "-//Arbortext//ENTITIES Font Filter 1.0//EN" "fontFilter.ent"
PUBLIC "-//Arbortext//ENTITIES Simple Attribute Cascader//EN" "simpleAttrCascader.ent"
资源
叠加溢出
我也看过
Validate XML using XSD, a Catalog Resolver, and JAXP DOM for XSLT
. 我觉得这不太可能解决我的问题,但可能是错误的。
在线的
我还查看了以下网站:
测试用例
我已经将Java代码、目录结构和XML上传到
http://aapro.net/CatalogTest.zip
应该可以向我的程序添加一些内容,它接受到test/doctypes文件夹(文件夹,而不是其中的目录文件)的路径,然后用程序提示的“validate”选项成功解析catalogtest.xml文件。其他(昂贵的)sgml/xml感知软件可以做到这一点。一旦给定了test/doctypes文件夹的绝对路径,目录解析器就应该能够按照test/doctypes/catalog文件中的catalog指令执行到test/other/forms/catalog文件,再执行到test/other/forms/forms.dtd。解析器应该能够解析test/other/forms/forms.dtd并使用它来验证test/catalogtest.xml。
实际上,整个过程应该能够处理这样的目录文件或catalog.xml文件,并且应该能够解析DTD或XSD文件,以及SGML或XML实例。但实际上我并不太关心SGML;在我的工作环境中,仍然只有一些milspec环境使用它。
多种方法?
我愿意尝试多个解析器和/或解析器,或者让用户进行选择。
内联Java代码
(也在上述zip文件中)
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class ParseXmlWithCatalog {
public static void main(String[] args) {
int validating = JOptionPane.showOptionDialog(null, "Do you want validation?", "Please choose \"Yes\" for validation",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, JOptionPane.YES_OPTION);
parseDoc(getFile(args), validating == JOptionPane.YES_OPTION);
}
private static boolean parseDoc(File inFile, boolean validate) {
if (inFile == null) {
JOptionPane.showMessageDialog(null, "Failure opening input XML.");
}
try {
/*
System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl");
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
LSParserFilter filter = new InputFilter();
builder.setFilter(filter);
*/
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
if (!validate) {
builderFactory.setValidating(false);
builderFactory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
}
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document testDoc = builder.parse(inFile.getPath());
System.out.println(testDoc.getFirstChild().getNodeName());
} catch (Exception exc) {
JOptionPane.showMessageDialog(null, "Failure parsing input XML: " + exc.getMessage());
return false;
}
return true;
}
public static File getFile(String[] args) {
if (args.length > 1) {
JOptionPane.showMessageDialog(null, "Too many arguments.");
return null;
}
if (args.length == 1) {
return new File(args[0]);
}
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(false);
fileChooser.setDialogTitle("Select 1 XML file");
FileNameExtensionFilter filter = new FileNameExtensionFilter("XML Files", "xml", "ditamap", "dita", "style");
fileChooser.setFileFilter(filter);
int response = fileChooser.showOpenDialog(null);
if (response != JFileChooser.APPROVE_OPTION) {
// aborted
return null;
}
return fileChooser.getSelectedFile();
}
}