我创建了一个Java应用程序来修改一些SVG文件。 这是我的问题: 我想在SVG文件的DOM中添加一个元素,以在矩形上创建链接。 SVG文件是从另一个应用程序生成的。 我需要用Java来做。
所以这就是我所做的:
我尝试了很多配置,使用SAX,DOM API来解析它,这是我成功从SVG文件创建文档的唯一方法。
这是我的SVGFile:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg ... xmlns:xlink="http://www.w3.org/1999/xlink" ....xmlns="http://www.w3.org/2000/svg" ...>
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs"/>
<g>
<defs id="defs1">
....define the clipath...
</defs>
HERE I WOULD LIKE TO INSERT OPEN A ELEMENT : <a ....>
<g font-size="11" transform="translate(2,212)" fill-opacity="1"fill="rgb(192,255,255)" text-rendering="geometricPrecision" font-family="sans-serif" stroke="rgb(192,255,255)" font-weight="bold" stroke-opacity="1">
<rect x="0" width="80" height="40" y="0" clip-path="url(#clipPath1)" stroke="none"/>
</g>
<g font-size="11" stroke-linecap="butt" transform="translate(2,212)" fill-opacity="1" fill="black" text-rendering="geometricPrecision" font-family="sans-serif" stroke-linejoin="round" stroke="black" font-weight="bold" stroke-opacity="1" stroke-miterlimit="0">
<rect fill="none" x="0" width="80" height="40" y="0" clip-path="url(#clipPath1)"/>
</g>
<g font-size="11" transform="translate(2,212)" fill-opacity="1" fill="black" text-rendering="geometricPrecision" font-family="sans-serif" stroke="black" font-weight="bold" stroke-opacity="1">
<text x="28" xml:space="preserve" y="12" clip-path="url(#clipPath4)"stroke="none" >Titre</text>
<line y2="12" fill="none" x1="28" clip-path="url(#clipPath4)" x2="52" y1="12"/>
</g>
</g>
</svg>
AND I WOULD LIKE TO CLOSE IT here : </a>
从我的SVG获取DOM文档的代码:
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
File file = new File ("D:/mySVGFile.svg");
String uri = file.toURI().toString();
Document doc = f.createDocument(uri);
要解析文档获取我做到了:
Element racine = doc.getDocumentElement();
String tag ="text"; // Because it's the only element I have store in an Array
NodeList liste = doc.getElementsByTagName(tag);
Element e = (Element) liste.item(0); // element text = Titre
Node target = e.getParentNode().getParentNode().getParentNode();
Element link = doc.createElement("a");
link.setAttribute("xlink:href", "DestinationFile.svg#67");
target.insertBefore(link, target);
以下是控制台错误:
org.w3c.dom.DOMException: The child node (type: 1, name: svg) is missing.
at org.apache.batik.dom.AbstractNode.createDOMException(AbstractNode.java:408)
at org.apache.batik.dom.AbstractParentNode.insertBefore(AbstractParentNode.java:78)
at SAXTagCount.main(SAXTagCount.java:60)
实际上我真的不知道如何在Java中为SVG文件创建这个元素。
先谢谢你的帮助!
吉姆
答案 0 :(得分:1)
该行
Element link = doc.createElement("a");
不正确。要创建SVG <a>
元素,或者实际上任何svg元素,您必须使用createElementNS即。
Element link = doc.createElementNS("http://www.w3.org/2000/svg", "a");
您的其他一个问题是您有太多的getParentNode()调用。文本元素的父级是其封闭的<g>
。其父级是另一个<g>
,其父级是<svg>
根元素,因此您的insertBefore尝试在<a>
根元素之前插入<svg>
,而不是<g>
允许。在我看来,你需要删除2个getParentNode()调用,将它放在正确的级别。
您还有其他各种问题,例如在正确的位置插入 - 不知何故,您需要找到<a>
元素,理想情况下,它会有ID或某种方式来识别它,否则您会有去搜索它。此外,您还需要收集您想要制作成<a>
个孩子的所有元素。您可以通过使用link.appendChild重新显示每个现有元素来使其成为target.insertBefore(link, target);
元素的子元素。但是,在一个答案中可以涵盖很多。
{{1}}
无效,因为您无法使用目标两次。论证应该是目标的孩子,而不是目标本身。
答案 1 :(得分:0)
/**
* Use the SAXSVGDocumentFactory to parse the given URI into a DOM.
*
* @param uri
* The path to the SVG file to read.
* @return A Document instance that represents the SVG file.
* @throws Exception
* The file could not be read.
*/
private Document createSVGDocument(String uri) throws IOException {
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
return factory.createDocument(uri);
}