【问题标题】:Java Create <a> element in SVG DOMJava 在 SVG DOM 中创建 <a> 元素
【发布时间】:2014-08-10 15:24:09
【问题描述】:

我创建了一个 Java 应用程序来修改一些 SVG 文件。 这是我的问题: 我想向我的 SVG 文件的 DOM 添加一个元素以在矩形上创建链接。 SVG 文件是从另一个应用程序生成的。 我需要用 Java 来做。

这就是我所做的:

  • 我使用 JASXP 尝试解析和修改我的 SVG 文件。

我尝试了许多配置,使用 SAX、DOM API 来解析它,这是我成功地从我的 SVG 文件创建文档的唯一方法。

这是我的 SVG 文件:

<?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 文件创建这个元素。

提前感谢您的帮助!

吉姆

【问题讨论】:

    标签: parsing dom svg sax batik


    【解决方案1】:

    线

    Element link = doc.createElement("a");
    

    不正确。要创建 SVG &lt;a&gt; 元素,或者实际上任何 svg 元素,您必须使用 createElementNS 即

    Element link = doc.createElementNS("http://www.w3.org/2000/svg", "a");
    

    您的其他问题之一是您有太多的 getParentNode() 调用。文本元素的父元素是其封闭的&lt;g&gt;。它的父级是另一个&lt;g&gt;,它的父级是&lt;svg&gt; 根元素,因此您的insertBefore 试图在&lt;svg&gt; 根元素之前插入&lt;a&gt;,这是不允许的。在我看来,您需要删除 2 个 getParentNode() 调用才能将其置于正确的级别。

    您还有其他各种问题,例如在正确的位置插入 - 不知何故,您需要找到 &lt;g&gt; 元素,理想情况下它应该有一个 id 或某种方式来识别它,否则您必须搜索它。此外,您还需要收集所有要制作成 &lt;a&gt; 子代的元素。您可以通过使用link.appendChild 重新设置每个现有元素的父级,使其成为&lt;a&gt; 元素的子元素。不过,一个答案涵盖了很多内容。

    target.insertBefore(link, target);
    

    也无效,因为您不能使用 target 两次。参数应该是目标的孩子,而不是目标本身。

    【讨论】:

    【解决方案2】:
    /**
     * 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-19
      • 2012-01-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2015-09-23
      • 2010-09-12
      • 2011-03-02
      相关资源
      最近更新 更多