Closed tomveich closed 1 year ago
If I try to convert any (valid) SVG, I keep getting this error.
This implies that your XML parser is not doing namespace handling, so my suggestion would be:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
transcoderInput.setXMLReader(reader);
or alternatively:
SAXParser parser = SAXParserFactory.newSAXParser()
XMLReader reader = parser.getXMLReader();
reader.setFeature("http://xml.org/sax/features/namespaces", true);
transcoderInput.setXMLReader(reader);
or whatever Android requires to set in order to support namespaces. It is weird, because http://xml.org/sax/features/namespaces
is supposed to be true
by default. Please let me know what works so I can put it in the FAQ.
That said, I would not expect EchoSVG to work on Android because that OS does not have the java.awt
package(s). I know that there is a Harmony-based open source replacement but I would be surprised if it is complete enough. Again, if you manage to run it on Android please let me know so I can put that on the FAQ.
None of the code you suggested affected the output. The error persists.
I found this library in the official android docs: https://developer.android.com/reference/org/xmlpull/v1/package-summary
but I couldn't find a reader() method there.
Thank you
None of the code you suggested affected the output. The error persists.
Then I'd suggest debugging what happens inside SAXDocumentFactory.startElement
when it is processing the svg
element. I mean checking which uri
is it reporting when the localName
is svg
. If uri
is null
as I say (because it's the only way I can reproduce your issue) then the XML parser is to blame, not EchoSVG.
I found this library in the official android docs:
https://developer.android.com/reference/org/xmlpull/v1/package-summary
but I couldn't find a reader() method there. Thank you
The XmlPullParser does not use SAX and is therefore incompatible with EchoSVG's DOM, although SAXDocumentFactory
could be modified to use it. If you are willing to provide a Pull Request providing that functionality, I could merge it. The XMLPull API is explained here:
https://www.xmlpull.org/v1/download/unpacked/doc/quick_intro.html
As much as I'd like to, I'm afraid I'm not experienced enough to provide such a PR. For my purpose, I am left to convert the images on backend.
As much as I'd like to, I'm afraid I'm not experienced enough to provide such a PR.
It is not too complicated once one understands the XmlPull API, but definitely a large amount of work. I don't think it would be worth the result (and a lot of people dislikes the XmlPull parser because it silently removes XML entities).
For my purpose, I am left to convert the images on backend.
There must be a way to get the namespaces with the SAX parser on Android, however even if you managed to solve that you'd probably get stuck on the AWT stuff: https://github.com/css4j/echosvg/wiki/FAQ#does-it-run-on-android
I'm closing this as not planned, feel free to reopen if you make any progress.
Incidentally, css4j-dom4j does support the XmlPull parser, see the XPP3Test
for an example:
So if you load the file with css4j-dom4j and then provide the DOM document to TranscoderInput
, that may work:
XHTMLDocumentFactory factory = XHTMLDocumentFactory.getInstance();
XPP3Reader reader = new XPP3Reader(factory);
Reader re = new FileReader(svgFile, "utf-8");
XHTMLDocument document = (XHTMLDocument) reader.read(re);
re.close();
TranscoderInput transcoderInput = new TranscoderInput(document);
PNGTranscoder pngTranscoder = PNGTranscoder()
pngTranscoder.transcode(transcoderInput, transcoderOutput);
And once EchoSVG 0.3.3 is released, you should be able to benefit from the support for namespaceless HTML documents. The idea would be to load the SVG file into a DOM document (from EchoSVG DOM, css4j's DOM or any other DOM, it does not matter), then create an html
element, append the document root to it, then append the html
element to the document (or just replace the nodes) and provide it to the TranscoderInput
:
DocumentFactory df = new SAXDocumentFactory(GenericDOMImplementation.getDOMImplementation());
String uri = svgFile.toURI().toString();
Reader re = new FileReader(svgFile, "utf-8");
Document document = df.createDocument(null, "svg", uri, re);
re.close();
Element html = document.createElement("html");
Element svg = document.getDocumentElement();
document.replaceChild(html, svg);
html.appendChild(svg);
// If the document has a DOCTYPE you'll have to remove it
TranscoderInput transcoderInput = new TranscoderInput(document);
PNGTranscoder pngTranscoder = PNGTranscoder()
pngTranscoder.transcode(transcoderInput, transcoderOutput);
Haven't tested but should work.
I opened a new issue for this. If I try to convert any (valid) SVG, I keep getting this error.
The compiler suggests it's being caused by the return statement in
SVGSVGElement getRootElement()
:File:
echosvg/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMDocument.java
Let me know if you need any specific details Thank you