0

古いプログラムからエクスポートされた大きな (1 MB) svg ファイルを読み込もうとしています。このプログラムまたはデータにアクセスできません。私はこのエクスポートされた svg ファイルしか持っていません。おそらく、このソースから新しくエクスポートされた svg ファイルを定期的にインポートする必要があります。Batik を使用して最初に見つけた問題は、このファイルを読み取るときに非常に厳密であるということです。たとえば、Firefox では、このファイルの読み取りと表示に問題はありません。Batik (文書内のいくつかの「カスタム」タグのため、Squiggle を含めて表示できません)。私が得る例外は...

org.w3c.dom.DOMException: The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: menu).
    at org.apache.batik.dom.AbstractNode.createDOMException(AbstractNode.java:408)
    at org.apache.batik.dom.svg.SVGDOMImplementation.createElementNS(SVGDOMImplementation.java:211)
    at org.apache.batik.dom.svg.SVGOMDocument.createElementNS(SVGOMDocument.java:372)
    at org.apache.batik.dom.util.SAXDocumentFactory.startElement(SAXDocumentFactory.java:625)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2756)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
    at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:431)
    at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:349)
    at org.apache.batik.dom.svg.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:200)
    at com.samsix.nrg.io.SvgFileImporter.importFile(SvgFileImporter.java:74)

...だから、完全には役に立たないリンクを使用して、バティック Dom 拡張機能を書く 私は次のように書くことができました...

    public ImportReport importFile( final String    uri )
    throws
        IOException
{
    String parser = XMLResourceDescriptor.getXMLParserClassName();
    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);

    SVGDOMImplementation    implementation = (SVGDOMImplementation) factory.getDOMImplementation( null );

    implementation.registerCustomElementFactory( "http://www.w3.org/2000/svg",
                                                 "menu",
                                                 new ExtensibleDOMImplementation.ElementFactory() {
                                                    @Override
                                                    public Element create( final String prefix,
                                                                           final Document doc )
                                                    {
                                                        System.out.println( "Element.create: " + prefix );
                                                        return new GenericElement( "prefix",
                                                                                   (org.apache.batik.dom.AbstractDocument) doc );
                                                    }
                                                } );

    SVGDocument    doc = (SVGDocument) factory.createDocument( uri );

    System.out.println( doc.getDocumentURI() );
}

しかし、同じエラーが発生します。 System.out.println() ステートメントがヒットすることはないため、ファクトリが正しく登録されていないようです。余談ですが、Firefoxのように理解できないことをスキップするように、Batikの厳密さを緩和する方法はありますか?

4

2 に答える 2

1

このフィルターを介してファイルを実行できるので、これは今のところ良い解決策です。近い将来、ユーザーが自分で svg ファイルをアップロードできるようにしたいと考えていますが、それにはもう少し堅牢なソリューションが必要になるでしょう。これが私が作成したxsltです...

<xsl:stylesheet version="1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!--Identity Transform.-->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svg:menu"/>
</xsl:stylesheet>

...そして私は走った...

java -jar /usr/share/java/saxon.jar original.svg svgfix.xslt > fixed.svg
于 2012-11-21T01:53:03.027 に答える
1

調査によると、Batik 1.7.0 の実装では、SVG 名前空間の要素をインターセプトする DOM 拡張を作成することはできません。登録されたファクトリのルックアップを行うコードにドロップスルーする時点で例外をスローします。これが意図的なものかどうかはわかりません。<menu>興味深いのは、現在のバージョンのSVG 仕様で定義されている要素がまったくないように見えることです。長い間廃止されてきたか、間違った名前空間に配置された拡張機能でした。うーん。

最も簡単な回避策は、XSLT スタイルシートを使用して<menu>要素を別の名前空間に再マップすることです (これは非常に簡単なスタイルシート IIRC です)。その後、カスタム ハンドラーを登録して、必要に応じてそれを処理します。

于 2012-11-20T23:24:23.033 に答える