I am trying to parse the RemotePage.getContent into a JDOM2 document and then output that document again.
I have so far run into the following problems:
I also perceive a possible problem with getting XMLOutputter to output the content without the body element (possible workaround: iterate over all element children of Document and output each element separately (but more cumbersome than it has to be)).
Also, I suspect that Confluence will prefer the lat1 (and other special characters) as character entities, and I don't know what XMLOutputter will do here.
Is there a simpler approach? Is there a way I can get the full XHTML for the page, including namespace, and DOCTYPE declarations?
Are there more correct ways of handling the problems I have encountered than the ones I've used so far?
Ok, now I have successfully round-tripped the XHTML content using the SOAP, API
First: the element to use to surround the RemotePage.getContents() before sending to the SAXReader, is:
<ac:confluence xmlns:ac="http://www.atlassian.com/schema/confluence/4/ac/" xmlns:ri="http://www.atlassian.com/schema/confluence/4/ri/" xmlns="http://www.atlassian.com/schema/confluence/4/">
The round-trip goes like this:
The re-serialized JDOM contained xmlns declarations not in the parsed input, and did not encode latin1 characters as character entities, but none of these created any problems that I could see.
A useful resource for me was the blog post "How to build a Confluence SOAP client in 5 minutes". I used m2e in eclipse to build the POM, so I had to add some extra stuff to make eclipse generate Java from the WSDL file and then compile the generated Java code.
Here is the class. The ApplicationProperties class is just a class that reads the META-INF/application.properties and provides static getters for the properties. In the getters System.property is checked for the same property, to let -D flags override the application.properties values:
public class PageReader { public static void main(String[] args) throws ServiceException, JDOMException, IOException { final ConfluenceSoapService service; ConfluenceSoapServiceServiceLocator serviceLocator = new ConfluenceSoapServiceServiceLocator(); service = serviceLocator.getConfluenceserviceV2(); // insert your account data here String token = service.login(ApplicationProperties.getSoapUser(), ApplicationProperties.getSoapPassword()); // Fetch a page to see what we have. String spaceKey = "~STEINARB"; String pageTitle = "This is a test page"; RemotePage page = service.getPage(token, spaceKey, pageTitle); String content = wrapContentInBodyElement(page.getContent()); System.out.println("content: " + page.getContent()); SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(new StringReader(content)); XMLOutputter xmlOutputter = new XMLOutputter(); String processedContent = xmlOutputter.outputElementContentString(doc.getRootElement()); processedContent = "<p>Hello</p>" + processedContent; System.out.println(); System.out.println("processedContent: " + processedContent); page.setContent(processedContent); service.updatePage(token, page, new RemotePageUpdateOptions(true, "Says Hello")); } private static String wrapContentInBodyElement(String content) throws IOException { String lat1Entities = IOUtils.toString(PageReader.class.getResourceAsStream("/xhtml/xhtml-lat1.ent")); return "<!DOCTYPE ac:confluence [ " + lat1Entities + "]> <ac:confluence xmlns:ac=\"http://www.atlassian.com/schema/confluence/4/ac/\" xmlns:ri=\"http://www.atlassian.com/schema/confluence/4/ri/\" xmlns=\"http://www.atlassian.com/schema/confluence/4/\" >" + content + "</ac:confluence>"; } }
Here is the POM file that will generate Java from WSDL and compile the generated Java:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>no.steria.steinarb</groupId> <artifactId>confluence-soap-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>confluence-soap-client</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>axis</groupId> <artifactId>axis</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>javax.xml</groupId> <artifactId>jaxrpc-api</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>commons-discovery</groupId> <artifactId>commons-discovery</artifactId> <version>0.4</version> </dependency> <dependency> <groupId>javax.xml.soap</groupId> <artifactId>saaj-api</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>axis</groupId> <artifactId>axis-wsdl4j</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.jdom</groupId> <artifactId>jdom</artifactId> <version>2.0.2</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.codehaus.mojo</groupId> <artifactId>axistools-maven-plugin</artifactId> <versionRange>[1.0,)</versionRange> <goals> <goal>wsdl2java</goal> </goals> </pluginExecutionFilter> <action> <execute /> </action> </pluginExecution> <pluginExecution> <pluginExecutionFilter> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <versionRange>[1.0,)</versionRange> <goals> <goal>parse-version</goal> <goal>add-source</goal> <goal>maven-version</goal> <goal>add-resource</goal> <goal>add-test-resource</goal> <goal>add-test-source</goal> </goals> </pluginExecutionFilter> <action> <execute> <runOnConfiguration>true</runOnConfiguration> <runOnIncremental>true</runOnIncremental> </execute> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>axistools-maven-plugin</artifactId> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/axistools/wsdl2java</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Not entirely there: I get an xmlns:ac declaration directly on the macro elements, that isn't there in the input.
In addition to not being on the input it exposes my dummy namespace URL.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The first bit of the output part (output only children of the root element) was easy:
String processedContent = xmlOutputter.outputElementContentString(doc.getRootElement());
I haven't figured out how to make it output character entities yet, though.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.