1

I'm trying to open, parse, edit and output an SVG document. So far I've edited/change the nodelist object how I want it to be, however, I'm having an issue saving my changes to the SVG document (by serializing). How might I be able to copy/save my changes to the SVG document and outputting to a file. My goal is to change the ID tag on certain objects (line/paths), I have to be able to find specific IDs, change it, then save back to the file (or a new file).

Here is my code (saving to file):

// Global variables
Logger logger = Logger.getLogger(DynamicLink.class.getSimpleName());
private final File PROJECT_DIRECTORY = new File("").getAbsoluteFile();
private final String PROJECT_PATH = "file.path";
Document doc;
private File svg;
private NodeList nodes;
private final ArrayList<Node> editedLines = new ArrayList();

private void saveSvg() {
    try {
        File newFile = new File(PROJECT_DIRECTORY, "test/LineTestEdited.svg");
        if (!newFile.exists()) {
            Files.copy(svg.toPath(), newFile.toPath());
        }
        DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();    
        DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("XML 3.0 LS 3.0");
        LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, "http://www.w3.org/TR/REC-xml");
        Document document = parser.parseURI(newFile.getPath());

        NodeList svgRoot = doc.getChildNodes();
        NodeList root = document.getChildNodes();
        int length = editedLines.size();

        for (int i = 0; i <= length-1; i++) {
            Node defaultNode = nodes.item(i+1);
            Node newNode = editedLines.get(i);

            String defaultName = defaultNode.getNodeName();
            String defualtValue = defaultNode.getNodeValue();

            String newName = newNode.getNodeName();
            String newValue = newNode.getNodeValue();
            String type = defaultNode.getBaseURI();

            if (newValue != null) {
                setNodeValue(newName, defualtValue, newValue, svgRoot);
            }
        }
        LSSerializer serial = impl.createLSSerializer();
        LSOutput output = impl.createLSOutput();
        output.setEncoding("UTF-8");
        output.setByteStream(new FileOutputStream(newFile));
        serial.write(document, output);

    } catch (Exception ex) {
        logger.log(Level.SEVERE, "Error occurred while exporting/saving SVG", ex);
    } 
}

And this is editing the nodelist (editedLines are the new changed ones). Everything else is just loading the document and global variables.

private void parseSvg() {
    int length = nodes.getLength();
    int index = 0;
    try {
        for (int i = 0; i <= length-1; i++) {
            Node node = nodes.item(i).cloneNode(true);
            String value = node.getNodeValue();
            String name = node.getNodeName();
            String type = node.getTextContent();

            if (!name.equals("svg")) {
                if (value != null) {
                    if (value.contains("Dynamic")) {
                        node.setNodeValue("Line_" + index);
                        editedLines.add(node);

                        index++;
                        System.out.println("Value: " + node.getNodeValue());
                    } else {
                        editedLines.add(node);
                    }
                } else {
                    editedLines.add(node);
                }
            }
        }
    } catch (Exception ex) {
        logger.log(Level.SEVERE, "Error occured while parsing SVG", ex);
    }
}

Extra stuff used:

private Node getNode(String tagName, String oldId) {
        NodeList list = doc.getElementsByTagName(tagName);

        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            Element element = (Element)node;
            //Element newEle = (Element)element.getElementsByTagName(tagName)
            String nodeId = element.getAttribute("id");

            if (nodeId.equals(oldId)) {
                return node;
            }
        }
        return null;
    }

    private void setNodeValue(String tagName, String oldId, String id, NodeList nodes) {
        Node node = getNode(tagName, oldId);
        //Node node = 
        if ( node == null )
            return;

        // Locate the child text node and change its value
        NodeList childNodes = node.getChildNodes();
        for (int y = 0; y < childNodes.getLength(); y++ ) {
            Node data = childNodes.item(y);
            if ( data.getNodeType() == Node.ATTRIBUTE_NODE ) {
                data.setNodeValue(id);
                return;
            }
        }
    }
Lloyd Smith
  • 77
  • 3
  • 16
  • Doesn't answer your question - just some friendly advice: It would be a good idea to look into Jaxb for your XML parsing/saving. It lets you represent your XML files with POJOs so it is easier to read and maintain. Not saying what you have there is bad, but it makes my eyes glaze over and puts me to sleep. – Loduwijk Jul 21 '17 at 18:05
  • What's Jaxb? a library? – Lloyd Smith Jul 21 '17 at 18:07
  • Yes, and it is part of Java. It handles converting plain-old-java-object fields into XML and back – Loduwijk Jul 21 '17 at 18:10
  • Ok, can you link me any examples using it to parse/edit SVG files? – Lloyd Smith Jul 21 '17 at 18:14
  • The top-rated & accepted answer of the following question was answered by the author of Jaxb and includes an example relevant to the question it answers: https://stackoverflow.com/questions/8186896/how-do-i-parse-this-xml-in-java-with-jaxb – Loduwijk Jul 21 '17 at 18:27
  • Yeah I have no idea what that's suppose to do nor is that what I'm looking for. I'm looking for something like this:https://stackoverflow.com/questions/28837786/how-to-find-and-replace-an-attribute-value-in-a-xml – Lloyd Smith Jul 21 '17 at 19:38

0 Answers0