kevzettler
kevzettler

Reputation: 5213

How to convert Confluence Storage Format XML to HTML?

I am pulling content from confluence using the REST API.

https://docs.atlassian.com/atlassian-confluence/REST/3.2/

The API returns confluence pages with a content property. The content is a mix of XHTML and proprietary XML tags. The XML is Confluence Storage Format:

https://confluence.atlassian.com/display/DOC/Confluence+Storage+Format

The custom XML tags are used for things like images, relative links, and attachments. If I render the content straight out the custom XML will not render.

I've found what looks like an endpoint that is supposed to convert the the format: https://docs.atlassian.com/confluence/latest/com/atlassian/confluence/xhtml/api/XhtmlContent.html

I don't think it is longer supported.

I've also found this project:

http://www.amnet.net.au/~ghannington/confluence/readme.html#wikifier

Which converts confluence XML into confluence wiki markup. The project comes with two .xsl sheets One sheet is confluence2wiki.xsl which handles the markup conversion, and the other is confluence2xhtml.xslwhich sounds like it would do the job but unfortunately the implementation is poor. It literally converts the confluence XML into XHTML that looks like the XML. So an image tag from the confluence XML unfortunately becomes:

<div class="extension-element">
  <p class="extension-element-markup">
    <span class="element-name">ac:image</span>
    <span class="attribute-name">ac:alt</span>
    <span class="markup">="</span>
    <span class="attribute-value">Example1.png</span>
    <span class="markup">"</span>
  </p>
  <div class="extension-element-contents">
    <div class="extension-element">
      <p class="extension-element-markup">
        <span class="element-name">ri:url</span>
        <span class="attribute-name">ri:value</span>
        <span class="markup">="</span>
        <span class="attribute-value">https://example.com/attachments/token/2ujwb0dm4jsorgk/?name=Omniata_Docs_Projects_Example1.png</span>
        <span class="markup">"</span>
      </p>
    </div>
  </div>
</div>

Which is not very helpful. Currently it looks like I will have to write my own xsl sheet based on the wkik xsl sheet. I'm hoping there is a less manual solution out there or someone has done this before.

Upvotes: 2

Views: 5972

Answers (3)

Zelle
Zelle

Reputation: 21

Similar like it was already shown in an other answer, but for me it was not clear that you have to use the xhtmlContent. You can easily get an instance of that via the constructor.

public class MyServlet extends HttpServlet {

    private Logger LOGGER = Logger.getLogger(getClass());

    private final PageManager pageManager;
    private final XhtmlContent xhtmlContent;


    public static final String PARAM_PAGE_ID = "pageId";


    public MyServlet( PageManager pageManager, XhtmlContent xhtmlContent) {
    this.pageManager = pageManager;
        this.xhtmlContent = xhtmlContent;
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        //fetch page or blogpost
        ContentEntityObject page = pageManager.getPage(Long.parseLong(request.getParameter(PARAM_PAGE_ID)));
        if (page == null) {
            page = pageManager.getBlogPost(Long.parseLong(request.getParameter(PARAM_PAGE_ID)));
        }
        if (page != null) {
            String htmlContent = "";
            final ConversionContext conversionContext = new DefaultConversionContext(page.toPageContext());
            try {
                htmlContent = xhtmlContent.convertStorageToView(page.getBodyAsString(), conversionContext);
            } catch (XMLStreamException e) {
                htmlContent = "ERROR ON EXPORT";
                LOGGER.error(e);
            } catch (XhtmlException e) {
                htmlContent = "ERROR ON EXPORT";
                LOGGER.error(e);
            }

        } else {
        //do some errorhandling here
    }
    //.. do something with the content .. render it in a velocity file for example
    }

You can render the data in a velocity file for example or write it direct in the response.

Upvotes: 0

sendmoreinfo
sendmoreinfo

Reputation: 592

Call the renderContent method via Remote API. There's also a convertWikiToStorageFormat method if your content is in older format.

Upvotes: 1

dvdsmpsn
dvdsmpsn

Reputation: 2869

If you need to do this, using a REST API, currently the best way would be to write a plugin and implement your own REST API that does the conversion for you.

Something like this should start you on your way by converting the storage format into HTML:

public String convertStorageToView(int pageId)
{
    Page page = pageManager.getById(pageId);        
    String storage = page.getBodyAsString();

    try
    {
        final ConversionContext conversionContext = new DefaultConversionContext(page.toPageContext());

        return xhtmlContent.convertStorageToView(storage, conversionContext);
    }
    catch (XhtmlException e)
    {
        e.printStackTrace();
    }
    catch (XMLStreamException e)
    {
        e.printStackTrace();
    }

    return null;
}

You'll also have to write the REST module.

Upvotes: 0

Related Questions