javaodftoolkit

Java odftoolkit, how to add node created from plain string into odf document


I have a code:

// -----------------------------------------------------------------

TextDocument resDoc = TextDocument.loadDocument( someInputStream );

Section section = resDoc.getSectionByName( "Section1" );  // this section does exist in the document

// create new node form String

String fragment = "<text:p text:style-name=\"P13\"><text:span text:style-name=\"T1\">Test</text:span></text:p>";

Node node = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new InputSource( new StringReader( fragment ) ) ).getDocumentElement();
node = section.getOdfElement().getOwnerDocument().importNode( node, true );

// append new node into section

section.getOdfElement().appendChild( node );

// -----------------------------------------------------------------

The code runs without a problem. But nothing does appear in the section in the result document. Please any idea how can I add new nodes created from string into the odf document?


Solution

  • I've got a solution from Svante Schubert from odf-users mailing group:

    The trick is to make the DocumentFactory namespace-aware and in addition, add a namespace to your text snippet. In detail this is being changed:

    OLD:

    String fragment = "<text:p text:style-name=\"P13\"><text:span text:style-name=\"T1\">Test</text:span></text:p>";
    Node node = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new
    

    InputSource(new StringReader(fragment ))).getDocumentElement();

    NEW:

    String fragment = "<text:p xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" text:style-name=\"P13\"><text:span text:style-name=\"T1\">Test</text:span></text:p>";
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    

    So based on his finding I came up with a method:

    private Node importNodeFromString( String fragment, Document ownerDokument ) {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware( true );
    
        Node node;
        try {
            node = dbf.newDocumentBuilder().parse( new InputSource( new StringReader( fragment ) ) ).getDocumentElement();
        }
        catch ( SAXException | IOException | ParserConfigurationException e )                {
            throw new RuntimeException( e );
        }
    
        node = ownerDokument.importNode( node, true );
        return node;
    }
    

    That can be used as:

    section.getOdfElement().appendChild(importNodeFromString(fragmment, section.getOdfElement().getOwnerDocument()))