Search code examples
androidsvgandroid-webview

Android: add a new element to a svg not working dynamically, but work manually


I have a big svg file that I read from assets as String and inject into a Webview. I need to add new element to this svg. My strategy was to replace the final </svg> by the content of the new element. At the end, I have this kind of structure

<svg>     
   content1
   content2
</svg>

Unfortunately, it doesn't work, impossible to see content2, even after removing all bad characters. However, when I log the new svg and test it online, I can see both contents. How it's possible? Here my code

Retrieve svg as string

val inputStream = context.assets.open("mydoc.svg")
appViewModel.updateSvgMap(inputStream.bufferedReader().use(BufferedReader::readText))

then webview.loadData(appUiState.svgContent, "text/html", "utf-8") And finally, the new content is added like that

 svgContent= svgContent.substring(0, content.indexOf("</svg>")) + newSvgContent

Have you any suggestions? I have the impression that the manipulation of string is not a good alternative, but then why?

Thanks


Solution

  • I found a solution, but I still don't know why it doesn't work before. The process was to transform the string svg into a Node Document, and then transform back the Document as String. And after, the new svg is well read

    From String to Document

    fun loadXMLFromString(xml: String): Document {
        val factory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
        val builder: DocumentBuilder = factory.newDocumentBuilder()
        val `is` = InputSource(StringReader(xml))
        return builder.parse(`is`)
    }
    

    From Document to String

    fun documentToString(document: Document): String? {
        try {
            val tf: TransformerFactory = TransformerFactory.newInstance()
            val trans: Transformer = tf.newTransformer()
            val sw = StringWriter()
            trans.transform(DOMSource(document), StreamResult(sw))
            return sw.toString()
        } catch (tEx: TransformerException) {
            tEx.printStackTrace()
        }
        return null
    }
    

    EDIT: finally, the best solution was to use loadDataWithBaseURL instead of loadData in the webview, even if the URL is senseless