Java 多个目录文件(以及 catalog.xml)和 DTD(以及 XSD)的目录解析器以及指向更多信息的指针,而不仅仅是 API?
Java catalog resolver for multiple catalog files (as well as catalog.xml) and DTDs (as well as XSDs) and pointer to more info than just the API?
我使用 PTC Arbortext Editor,它最初是在 1980 年代末 XML (SGML) 之前的日子里编写的。 Java 应用程序使用 org.custommonkey.xmlunit 来区分 XML 文件。
diff 工具无法解析文件,其中文件期望(在 Windows 上)以分号分隔的绝对路径列表到各种目录文件位置,其中它查找 catalog
and/or catalog.xml
个文件。这些可以使用 CATALOG
指令。使用 PUBLIC
标识符映射到相对于特定目录文件的路径。
我正在使用此目录信息解析 XML,其中可能包含文件实体以及 XML 内含物。
对于某些用例,我可以设置验证 false
并且有效(假设这两个文件有效是合理的)但对于某些文件,我必须读取目录信息以解析文件实体XML.
我可以要求用户提供其顶级目录位置的绝对路径列表。但是,我在选择解析器并将其集成到我的代码中时感到迷茫。
我正在使用 Java 1.8,但如果可以 help/simplify,我不介意使用 10。看起来 9 对 javax.xml.catalog 有一些简单的支持,但不在 1.8 或 10.
中
如果重要的话,我可以提供我的解析代码,但我不会局限于任何一个解析器。
我的代码如下。为了 setValidating(false)
.
,我从 LSParser
切换到 DocumentBuilder
以下是我希望能够使用的其中一个文件的一些摘录:
<?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。我觉得它不太可能解决我的问题,但可能是错误的。
在线
我还查看了以下网站:
- http://magicmonster.com/kb/prg/java/xml/dom/xml_resolver.html
- http://magicmonster.com/kb/prg/java/xml/resolvers.html
- http://openjdk.java.net/jeps/268
- https://blog.xml.rocks/early-review-of-java-9-xml-catalogs/
- https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/org/apache/commons/configuration/resolver/CatalogResolver.html
- https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/org/apache/commons/configuration/resolver/CatalogResolver.html#setCatalogFiles(java.lang.String)
- https://docs.oracle.com/javase/10/docs/api/javax/xml/catalog/CatalogManager.html
- https://docs.oracle.com/javase/9/docs/api/javax/xml/catalog/CatalogManager.html
- https://norman.walsh.name/2007/02/06/xmlresolver
测试用例
我已将 Java 代码、目录结构和 XML 上传到 http://aapro.net/CatalogTest.zip
应该可以向我的程序添加一些东西,它接受 Test/doctypes 文件夹(该文件夹,而不是其中的目录文件)的路径,然后 CatalogTest.xml 文件应该可以成功解析使用程序提示的 "Validate" 选项。其他(昂贵的)SGML/XML-aware 软件可以这样做。目录解析器,一旦给出 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;在我的工作环境中,只有少数军用规格情况会使用它。
多种方法?
我愿意尝试不止一种解析器 and/or 解析器,或者让用户做出选择。
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();
}
}
Apache XML Commons Resolver 支持 OASIS XML 目录和旧的 OASIS TR9401 目录格式。参见 https://xerces.apache.org/xml-commons/components/resolver/。
要在您的测试项目中启用目录查找,请执行以下操作:
从 http://xerces.apache.org/mirrors.cgi#binary 下载 XML Commons Resolver。
提取 resolver.jar 并将其添加到类路径中。
创建一个名为 CatalogManager.properties 的文本文件并将其放在类路径中。在此文件中,添加目录路径:
catalogs=./doctypes/catalog
目录文件的位置也可以通过 xml.catalog.files
Java 系统 属性.
指定
在ParseXmlWithCatalog.java中,添加import
语句并创建CatalogResolver
的实例。将该实例设置为解析器的 EntityResolver
:
import org.apache.xml.resolver.tools.CatalogResolver;
...
CatalogResolver cr = new CatalogResolver();
builder.setEntityResolver(cr);
我正在 post 编写此示例代码,因为它结合了 mzjn 所建议的 org.apache.xml.resolver.tools.CatalogResolver 的使用,并成功地与我在 http://aapro.net/CatalogTest.zip 的示例一起使用。也就是说,如果我 运行 它,并用是(我想要验证)回答第一个提示,用 Test\doctypes 文件夹的绝对路径回答第二个提示,然后浏览到 CatalogTest.xml,它成功地遵循 Test\doctypes 中的 CATALOG 指令到“../other/forms/catalog”,后者又指定 DTD 的位置:PUBLIC "-//Test//Forms Document Type// EN" "forms.dtd",并告诉我我的顶级节点称为 "form"。
此时,我将把这个解决方案合并到我的 XML diff 程序中。如果我发现需要调整以处理多条目目录路径 and/or 处理目录和 catalog.xml 文件的混合,我将 post 进行更新。但这可能需要几周(或更长时间),我认为这段代码已经到了可能有人会觉得有用的地步。
import java.io.File;
import java.io.FilenameFilter;
import java.util.Map.Entry;
import java.util.Properties;
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.apache.xml.resolver.tools.CatalogResolver;
import org.w3c.dom.Document;
public class ParseXmlWithCatalog {
// Offer end-user the convenience of not having to specify which will be used,
// catalog and/or catalog.xml.
private static FilenameFilter catalogFileFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.equals("catalog") || name.equals("catalog.xml")) {
return true;
} else {
return false;
}
}
};
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);
if (validating == JOptionPane.YES_OPTION) {
String catPath = JOptionPane.showInputDialog(null,
"Please enter semi-colon-separated list of absolute paths to catalog folders, in desired search order; these are the locations of catalog or catalog.xml files, not the filenames.",
"Enter catalog path", JOptionPane.QUESTION_MESSAGE);
String[] catLocs = catPath.split(";");
StringBuilder sb = new StringBuilder();
for (String catLoc : catLocs) {
File[] catFiles = new File(catLoc).listFiles(catalogFileFilter);
for (File catFile : catFiles) {
if (sb.length() > 0) {
sb.append(";");
}
sb.append(catFile.toURI());
}
}
System.setProperty("xml.catalog.files", sb.toString());
System.out.println(
"Using the following top-level catalog files:\n" + System.getProperty("xml.catalog.files"));
System.setProperty("relative-catalogs", "yes");
}
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 {
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();
CatalogResolver resolver = new CatalogResolver();
builder.setEntityResolver(resolver);
Document testDoc = builder.parse(inFile.getPath());
JOptionPane.showMessageDialog(null,
"The top level node is \"" + 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();
}
}
我使用 PTC Arbortext Editor,它最初是在 1980 年代末 XML (SGML) 之前的日子里编写的。 Java 应用程序使用 org.custommonkey.xmlunit 来区分 XML 文件。
diff 工具无法解析文件,其中文件期望(在 Windows 上)以分号分隔的绝对路径列表到各种目录文件位置,其中它查找 catalog
and/or catalog.xml
个文件。这些可以使用 CATALOG
指令。使用 PUBLIC
标识符映射到相对于特定目录文件的路径。
我正在使用此目录信息解析 XML,其中可能包含文件实体以及 XML 内含物。
对于某些用例,我可以设置验证 false
并且有效(假设这两个文件有效是合理的)但对于某些文件,我必须读取目录信息以解析文件实体XML.
我可以要求用户提供其顶级目录位置的绝对路径列表。但是,我在选择解析器并将其集成到我的代码中时感到迷茫。
我正在使用 Java 1.8,但如果可以 help/simplify,我不介意使用 10。看起来 9 对 javax.xml.catalog 有一些简单的支持,但不在 1.8 或 10.
中如果重要的话,我可以提供我的解析代码,但我不会局限于任何一个解析器。
我的代码如下。为了 setValidating(false)
.
LSParser
切换到 DocumentBuilder
以下是我希望能够使用的其中一个文件的一些摘录:
<?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。我觉得它不太可能解决我的问题,但可能是错误的。
在线
我还查看了以下网站:
- http://magicmonster.com/kb/prg/java/xml/dom/xml_resolver.html
- http://magicmonster.com/kb/prg/java/xml/resolvers.html
- http://openjdk.java.net/jeps/268
- https://blog.xml.rocks/early-review-of-java-9-xml-catalogs/
- https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/org/apache/commons/configuration/resolver/CatalogResolver.html
- https://commons.apache.org/proper/commons-configuration/javadocs/v1.10/apidocs/org/apache/commons/configuration/resolver/CatalogResolver.html#setCatalogFiles(java.lang.String)
- https://docs.oracle.com/javase/10/docs/api/javax/xml/catalog/CatalogManager.html
- https://docs.oracle.com/javase/9/docs/api/javax/xml/catalog/CatalogManager.html
- https://norman.walsh.name/2007/02/06/xmlresolver
测试用例
我已将 Java 代码、目录结构和 XML 上传到 http://aapro.net/CatalogTest.zip
应该可以向我的程序添加一些东西,它接受 Test/doctypes 文件夹(该文件夹,而不是其中的目录文件)的路径,然后 CatalogTest.xml 文件应该可以成功解析使用程序提示的 "Validate" 选项。其他(昂贵的)SGML/XML-aware 软件可以这样做。目录解析器,一旦给出 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;在我的工作环境中,只有少数军用规格情况会使用它。
多种方法?
我愿意尝试不止一种解析器 and/or 解析器,或者让用户做出选择。
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();
}
}
Apache XML Commons Resolver 支持 OASIS XML 目录和旧的 OASIS TR9401 目录格式。参见 https://xerces.apache.org/xml-commons/components/resolver/。
要在您的测试项目中启用目录查找,请执行以下操作:
从 http://xerces.apache.org/mirrors.cgi#binary 下载 XML Commons Resolver。
提取 resolver.jar 并将其添加到类路径中。
创建一个名为 CatalogManager.properties 的文本文件并将其放在类路径中。在此文件中,添加目录路径:
catalogs=./doctypes/catalog
目录文件的位置也可以通过
xml.catalog.files
Java 系统 属性. 指定
在ParseXmlWithCatalog.java中,添加
import
语句并创建CatalogResolver
的实例。将该实例设置为解析器的EntityResolver
:import org.apache.xml.resolver.tools.CatalogResolver; ... CatalogResolver cr = new CatalogResolver(); builder.setEntityResolver(cr);
我正在 post 编写此示例代码,因为它结合了 mzjn 所建议的 org.apache.xml.resolver.tools.CatalogResolver 的使用,并成功地与我在 http://aapro.net/CatalogTest.zip 的示例一起使用。也就是说,如果我 运行 它,并用是(我想要验证)回答第一个提示,用 Test\doctypes 文件夹的绝对路径回答第二个提示,然后浏览到 CatalogTest.xml,它成功地遵循 Test\doctypes 中的 CATALOG 指令到“../other/forms/catalog”,后者又指定 DTD 的位置:PUBLIC "-//Test//Forms Document Type// EN" "forms.dtd",并告诉我我的顶级节点称为 "form"。
此时,我将把这个解决方案合并到我的 XML diff 程序中。如果我发现需要调整以处理多条目目录路径 and/or 处理目录和 catalog.xml 文件的混合,我将 post 进行更新。但这可能需要几周(或更长时间),我认为这段代码已经到了可能有人会觉得有用的地步。
import java.io.File;
import java.io.FilenameFilter;
import java.util.Map.Entry;
import java.util.Properties;
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.apache.xml.resolver.tools.CatalogResolver;
import org.w3c.dom.Document;
public class ParseXmlWithCatalog {
// Offer end-user the convenience of not having to specify which will be used,
// catalog and/or catalog.xml.
private static FilenameFilter catalogFileFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.equals("catalog") || name.equals("catalog.xml")) {
return true;
} else {
return false;
}
}
};
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);
if (validating == JOptionPane.YES_OPTION) {
String catPath = JOptionPane.showInputDialog(null,
"Please enter semi-colon-separated list of absolute paths to catalog folders, in desired search order; these are the locations of catalog or catalog.xml files, not the filenames.",
"Enter catalog path", JOptionPane.QUESTION_MESSAGE);
String[] catLocs = catPath.split(";");
StringBuilder sb = new StringBuilder();
for (String catLoc : catLocs) {
File[] catFiles = new File(catLoc).listFiles(catalogFileFilter);
for (File catFile : catFiles) {
if (sb.length() > 0) {
sb.append(";");
}
sb.append(catFile.toURI());
}
}
System.setProperty("xml.catalog.files", sb.toString());
System.out.println(
"Using the following top-level catalog files:\n" + System.getProperty("xml.catalog.files"));
System.setProperty("relative-catalogs", "yes");
}
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 {
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();
CatalogResolver resolver = new CatalogResolver();
builder.setEntityResolver(resolver);
Document testDoc = builder.parse(inFile.getPath());
JOptionPane.showMessageDialog(null,
"The top level node is \"" + 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();
}
}