Batik copy element from one document to another

714 views Asked by At

I'm trying to compose an svg with batik from elements from a source document. This works as long as the elements don't reference things defined in the defs section (like gradients or filters). But when a filter is referenced I get an exception. I tried to also copy over the defs section but that didn't help.

String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
Document source = factory.createDocument("source", getClass().getResourceAsStream("/artwork/source.svg"));

SVGOMDocument target = (SVGOMDocument) domImpl.createDocument(svgNS, "svg", null);
Node defs = source.getElementsByTagName("defs").item(0).cloneNode(true);
target.adoptNode(defs);
target.getRootElement().appendChild(defs);

BridgeContext ctx = new BridgeContext(new UserAgentAdapter());
GVTBuilder builder = new GVTBuilder();
builder.build(ctx, target);

Element sourceEl = getElementByXPath(source,
        "//*[@id='IMAGES']/*[@id='" + selection.getImageSet() + "']/*[@id='"
                + suit.abbreviation() + value + "-" + selection.getImageSet() + "']");
SVGOMElement complete = (SVGOMElement) sourceEl.cloneNode(true);
target.adoptNode(complete);
target.getDocumentElement().appendChild(complete);

Rectangle2D completeBBox = builder.build(ctx, complete).getSensitiveBounds();

The last line gives the exception. Any help would be appreciated.

EDIT:

If I save the target svg after adding the defs section and then reload it again it works. But I would like to avoid this aditional step.

1

There are 1 answers

0
gerrit On

I found a solution to avoid the extra save/load. Use importNode instead of clone/adopt for the defs.

Node defs = target.importNode(source.getElementsByTagName("defs").item(0), true);
target.getRootElement().appendChild(defs);