【发布时间】:2017-10-17 04:01:55
【问题描述】:
由于 SVG 是一个常规的 XML 文件,并且 ImageTranscoder.transcode() API 接受 org.w3c.dom.Document,因此相应的 TranscoderInput 构造函数接受 org.w3c.dom.Document;有人会期望使用 Java 股票 XML 解析器加载和解析文件会起作用:
TranscoderInput input = new TranscoderInput(loadSvgDocument(new FileInputStream(svgFile)));
BufferedImageTranscoder t = new BufferedImageTranscoder();
t.transcode(input, null);
其中loadSvgDocument()方法定义为:
Document loadSvgDocument(String svgFileName, InputStream is) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// using stock Java 8 XML parser
Document document;
try {
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.parse(is);
} catch (...) {...}
return document;
}
它不起作用。我遇到了奇怪的强制转换异常。
Exception in thread "main" java.lang.ClassCastException: org.apache.batik.dom.GenericElement cannot be cast to org.w3c.dom.svg.SVGSVGElement
at org.apache.batik.anim.dom.SVGOMDocument.getRootElement(SVGOMDocument.java:235)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:193)
at org.apache.batik.transcoder.image.ImageTranscoder.transcode(ImageTranscoder.java:92)
at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:142)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:156)
注意:BufferedImageTranscoder 类是我的类,根据 Batik 蓝图创建,扩展了 ImageTranscoder,后者又扩展了上面堆栈跟踪中提到的 SVGAbstractTranscoder。
很遗憾我不能使用 Batik 自己的解析器,SAXSVGDocumentFactory:
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
svgDocument = (SVGDocument) f.createDocument(..);
我正在尝试渲染Papirus SVG icons,但它们都有<svg ... version="1">,而SAXSVGDocumentFactory 不喜欢这样,并且在createDocument(..) 上失败了Unsupport SVG version '1'。他们可能意味着不支持。
Exception in thread "main" java.lang.RuntimeException: Unsupport SVG version '1'
at org.apache.batik.anim.dom.SAXSVGDocumentFactory.getDOMImplementation(SAXSVGDocumentFactory.java:327)
at org.apache.batik.dom.util.SAXDocumentFactory.startElement(SAXDocumentFactory.java:640)
. . .
at org.apache.batik.anim.dom.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:225)
将文件本身中的version="1" 更改为version="1.0" 可以解决问题,并且图标为我呈现得很好。但是有数百(数千)个图标,修复它们很乏味,我会有效地为他们的项目创建一个端口。这对我来说不是前进的道路。使用 DOM API 在运行时进行修复要容易得多:
Element svgDocumentNode = svgDocument.getDocumentElement();
String svgVersion = svgDocumentNode.getAttribute("version");
if (svgVersion.equals("1")) {
svgDocumentNode.setAttribute("version", "1.0");
}
但这只能通过普通的 Java XML 解析器来完成,Batik XML 解析器在生成文档之前,在到达这段代码之前太早了。但是当我使用股票 XML 解析器时,修复版本,然后 Batik Transcoder (rasterizer) 不喜欢它。所以我在这里碰壁了。
是否有来自库存 XML 解析器的转换器产生 org.w3c.dom.Document 和蜡染兼容 org.w3c.dom.svg.SVGDocument?
【问题讨论】: