使用Saxon处理SVG时自动添加空xmlns属性的解决方法
解决Saxon序列化SVG时添加空
xmlns=""属性的问题 问题根源
你的DOM解析器配置存在矛盾:既启用了namespaceAware,又禁用了SAX的namespaces特性,导致解析后的SVG元素没有正确绑定到SVG标准命名空间(http://www.w3.org/2000/svg)。Saxon的XML序列化器对命名空间规则的遵循比Xerces更严格,当根元素属于SVG命名空间,但子元素(如<g>、<defs>)处于无命名空间状态时,会自动添加xmlns=""显式声明,而浏览器仅识别属于SVG命名空间的元素,因此导致SVG显示空白。
解决方案
1. 修复DOM解析器的命名空间配置
移除禁用namespaces特性的错误代码,确保解析器正确处理XML命名空间:
public void doStuff(File sourceF, File destination) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { dbf.setValidating(false); dbf.setNamespaceAware(true); // 保持命名空间感知能力 // 删除这行错误配置:dbf.setFeature("http://xml.org/sax/features/namespaces", false); dbf.setFeature("http://xml.org/sax/features/validation", false); dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(sourceF); // DOM操作时注意:所有元素必须保留SVG命名空间 // 例如移动子元素时,不要修改元素的命名空间URI // 序列化SVG DOMSource source = new DOMSource(doc); try (FileOutputStream fos = new FileOutputStream(destination); Writer out = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) { StreamResult result = new StreamResult(out); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 显式设置默认输出命名空间为SVG URI,让子元素自动继承 transformer.setOutputProperty( "http://saxon.sf.net/feature/defaultOutputNamespace", "http://www.w3.org/2000/svg" ); transformer.transform(source, result); } } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) { e.printStackTrace(); } }
2. 确保DOM操作时元素命名空间正确
如果你的DOM操作涉及创建新元素或移动元素,必须使用带命名空间的API:
- 创建新元素:使用
doc.createElementNS("http://www.w3.org/2000/svg", "g")而非createElement("g") - 移动子元素时,确保目标父元素同样属于SVG命名空间,避免元素脱离命名空间上下文
3. 可选:添加Saxon特定序列化参数
如果上述调整仍有问题,可添加更多Saxon专属参数优化序列化行为:
// 禁止输出未声明的命名空间前缀 transformer.setOutputProperty("http://saxon.sf.net/feature/serialize-undeclared-namespaces", "false"); // 确保输出格式紧凑(可选) transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
内容的提问来源于stack exchange,提问作者jpprade
相关产品推荐
相关产品推荐

