forked from Klortho/DtdAnalyzer
-
Notifications
You must be signed in to change notification settings - Fork 11
/
DtdSchematron.java
137 lines (112 loc) · 4.57 KB
/
DtdSchematron.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* DtdSchematron.java
*/
package gov.ncbi.pmc.dtdanalyzer;
import org.apache.commons.cli.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;
import org.apache.xml.resolver.tools.*;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Creates a Schematron from a DTD.
*/
public class DtdSchematron {
private static App app;
/**
* The list of all of the options that this application can take, in the order
* that they will appear in the usage message.
*/
private static String[] optList = {
"help", "version", "system", "doc", "public",
"full",
"catalog", "title", "roots", "docproc", "markdown", "param"
};
/**
* The set of options that are unique to this application
*/
private static HashMap customOpts = initCustomOpts();
/**
* This inner class will be invoked for each of the command-line options that was given.
* If it is a custom option, handle it here, otherwise, kick it back to App.
*/
private static OptionHandler optHandler = new OptionHandler() {
public boolean handleOption(Option opt) {
String optName = opt.getLongOpt();
if (optName.equals("full")) {
full = true;
return true;
}
return false;
}
};
// DtdSchematron-specific command line option values
private static boolean full = false;
/**
* Main execution point. Checks arguments, then converts the DTD into XML.
* This application currently uses Xerces and
* Saxon because these are known to work well and will be bundled with this
* distribution. However, other implementations can be specified through the
* System properties.
*/
public static void main (String[] args) {
app = new App(args, optList, optHandler, customOpts, true,
"dtdschematron {[-s] <system-id> | -d <xml-file> | -p <public-id>} " +
"[-f] [-c <catalog>] [-t <title>] [<out>]",
"\nThis generates a schematron file from a DTD."
);
app.initialize();
// This parses the DTD, and corrals the data into a model:
ModelBuilder model =
new ModelBuilder(app.getDtdSpec(), app.getRoots(), app.getResolver());
XMLWriter writer = new XMLWriter(model);
// Now run the XSLT transformation. This will be the dtdschematron.xsl
// stylesheet
try {
InputStreamReader reader = writer.getXML();
File xslFile = new File(app.getHome(), "xslt/dtdschematron.xsl");
Transformer xslt =
TransformerFactory.newInstance().newTransformer(new StreamSource(xslFile));
ArrayList xsltParams = app.getXsltParams();
int numXsltParams = xsltParams.size() / 2;
if (numXsltParams > 0) {
for (int i = 0; i < numXsltParams; ++i) {
xslt.setParameter((String) xsltParams.get(2*i), (String) xsltParams.get(2*i+1));
}
}
// Get the full option, if given, and pass that in.
xslt.setParameter("complete", full ? "yes" : "no");
// Use this constructor because Saxon always
// looks for a system id even when a reader is used as the source
// If no string is provided for the sysId, we get a null pointer exception
Source xmlSource = new StreamSource(reader, "");
xslt.transform(xmlSource, app.getOutput());
}
catch (Exception e) {
System.err.println("Could not run the transformation: " + e.getMessage());
e.printStackTrace(System.out);
}
}
/**
* Initialize any application-specific command line options here. These can also
* override the common options, if, for example, you want to change the usage
* message. You can even override the usage message, but still let the App class
* handle the option.
*/
private static HashMap initCustomOpts() {
HashMap _opts = new HashMap();
_opts.put("full",
OptionBuilder
.withLongOpt("full")
.withDescription("If this option is given, then a complete schematron " +
"will be generated from the DTD, as opposed to just extracting the " +
"rules in the annotations.")
.create('f')
);
return _opts;
}
}