XSL transformation operation

Oxygen general issues.
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

XSL transformation operation

Post by xsaero00 »

I am trying to write an operation where I can use a short XSLT script to change a fragment of the document into something else.

It would work as following: You would select a chunk of document or position your cursor in the document and the chunk of document will be selected by an XPath (probably self::* but this could be a parameter). Then in the operation you would make sure that the chunk is valid XML (add root element, expand selection to include full elements) and apply XSLT transformation to it (XSL string would be a parameter too), then you would insert the result of transformation into document (insertLocation, insertPosition, schemaAware arguments) and optionally (argument too) remove old content.

This operation could replace 90% percent of operations in oXygen (at least in my framework). Do you think this is feasible? How do I go about writing one. Mainly I am interested in how to do XSL transformation inside operation code and how to make sure to end up with valid XML when using selection.
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: XSL transformation operation

Post by Radu »

Hi Mike,

To be on the safe side you should always try to wrap the XML fragment in an artificial element and unwrap it after the stylesheet is applied.
We have API to create an XSLT transformer.
The code would be something like:

Code: Select all

    try {
AuthorDocumentFragment frag = authorAccess.getDocumentController().createDocumentFragment(authorAccess.getEditorAccess().getSelectionStart(), authorAccess.getEditorAccess().getSelectionEnd() - 1);
//This XML content should be valid if surrounded in an artificial root
String fragXML = authorAccess.getDocumentController().serializeFragmentToXML(frag);
//You can decide for consistency to always surround it in an artificial root
//The XSL can also be constructed to output the artificial root intact and thus you can strip the artificial root before insertion.
//You can use a longer random name for the root wrapper in order not to have by any chance in the XML fragment a node with the same name.
String fragWellFormed = "<root>" + fragXML + "</root>";
Transformer transformer = authorAccess.getXMLUtilAccess().createXSLTTransformer(new SAXSource(new InputSource(new StringReader(
//Stylesheet content here, you can also use a location resource. This sample XSL below is just an indentity transform.
"<xsl:stylesheet version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
" <xsl:output method=\"xml\"/>\n" +
" <!-- Match document -->\n" +
" <xsl:template match=\"/\">\n" +
" <xsl:apply-templates mode=\"copy\" select=\".\"/>\n" +
" </xsl:template>\n" +
" <!-- Deep copy template -->\n" +
" <xsl:template match=\"*|text()|@*\" mode=\"copy\">\n" +
" <xsl:copy>\n" +
" <xsl:apply-templates mode=\"copy\" select=\"@*\"/>\n" +
" <xsl:apply-templates mode=\"copy\"/>\n" +
" </xsl:copy>\n" +
" </xsl:template>\n" +
" <!-- Handle default matching -->\n" +
" <xsl:template match=\"*\"/>\n" +
"</xsl:stylesheet>\n" +
""))), new URL[0],
//Full power of XSLT 2.0
XMLUtilAccess.TRANSFORMER_SAXON_ENTERPRISE_EDITION);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
transformer.transform(new StreamSource(new StringReader(fragWellFormed)), result);

System.err.println("processed XML " + writer.toString());
//Now strip everyting before and including the <root> and everything after and including the </root> from the processed XML and insert it back using.
//authorAccess.getDocumentController().insertXMLFragment(xmlFragment, offset)
} catch (Exception e1) {
authorAccess.getWorkspaceAccess().showErrorMessage(e1.getMessage());
}
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re: XSL transformation operation

Post by xsaero00 »

Thanks you. The code will get me started. I agree with adding an artificial root element to selected fragment.

What if I have the selection that starts in a middle of one paragraph and ends in the middle of other? Will the code still produce valid XML?
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: XSL transformation operation

Post by Radu »

Hi,

Even if the selection can sometimes (many times) be considered to correspond to not well formed XML, any AuthorDocumentFragment produced using our API from the selection will be well formed XML (we will add start tags and end tags to the selection content to make it well formed).
So no need to worry about this.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply