Linkwerk Logo

Transforming XML to WordML - Determining Image Sizes

The first part of transforming XML to WordML is similar to many other transformations. One thing is special when generating WordML markup: WordML requires you to set the size of linked images (in contrary to embedded base64-encoded images).

We update our invitation.xml to include a reference to an image:

<invitation>
<picture file="birthday.jpg" scale="0.3"></picture>...
</invitation>

There's a new element named picture, which contains a reference to a JPG image on the harddisk and a scaling factor.

Unfortunately XSLT has no means to determine the size of an image. But Java has... Consequently we wrote our own XSLT extensions named PicMe (Picture Metadata) based on standard Java classes, which reads the file an provides an XSLT stylesheet with the required image dimensions.

The usage is quite simply: You need to declare a namespace prefix for PicMe and call the method getXMLMetaData() with the filename as the only argument. getXMLMetaData() returns the image information as an XML structure. The child elements width and height carry width/height in pixels. The extract of the updated XSLT is shown here:

<xslt:stylesheet xmlns:xslt="http://www.w3.org/1999/XSL/Transform" version="1.0">
...
<xslt:template match="invitation">
...
<word:body xmlns:word="http://schemas.microsoft.com/office/word/2003/wordml">
<xslt:variable name="width" select="round(number(/invitation/picture/@scale) * number(PicMe:getXMLMetaData(string(/invitation/picture/@file))/width))"></xslt:variable>
<xslt:variable name="height" select="round(number(/invitation/picture/@scale) * number(PicMe:getXMLMetaData(string(/invitation/picture/@file))/height))"></xslt:variable>
<w:pict xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml">
<v:shapetype xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:o="urn:schemas-microsoft-com:office:office" id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
<v:stroke joinstyle="miter"></v:stroke>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"></v:f>
<v:f eqn="sum @0 1 0"></v:f>
<v:f eqn="sum 0 0 @1"></v:f>
<v:f eqn="prod @2 1 2"></v:f>
<v:f eqn="prod @3 21600 pixelWidth"></v:f>
<v:f eqn="prod @3 21600 pixelHeight"></v:f>
<v:f eqn="sum @0 0 1"></v:f>
<v:f eqn="prod @6 1 2"></v:f>
<v:f eqn="prod @7 21600 pixelWidth"></v:f>
<v:f eqn="sum @8 21600 0"></v:f>
<v:f eqn="prod @7 21600 pixelHeight"></v:f>
<v:f eqn="sum @10 21600 0"></v:f>
</v:formulas>
<v:path xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:o="urn:schemas-microsoft-com:office:office" o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path>
<o:lock xmlns:o="urn:schemas-microsoft-com:office:office" v:ext="edit" aspectratio="t"></o:lock>
</v:shapetype>
<v:shape xmlns:v="urn:schemas-microsoft-com:vml" id="_x0000_i1025" type="#_x0000_t75" style="width:{$width}px;height:{$height}px;mso-position-horizontal:absolute">
<v:imagedata src="{/invitation/picture/@file}"></v:imagedata>
</v:shape>
</w:pict>
...
</word:body>
...
</xslt:template>
</xslt:stylesheet>

Finally you might want to take a look at the result document in Word: You can download a Screenshot or a Zip-File with the WordML- and Jpeg-File.