Solved

Processing Base 64 Image in XML

Posted on 2013-06-25
1
400 Views
Last Modified: 2013-07-23
Experts,

How can I process Binary ImageData using Saxon and output a file?  I want to include the filepath in the XML to the image.

Below is my XSLT file, which works perfectly and attached is a sample XML.

<!-- Begin XST Style Sheet -->


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" exclude-result-prefixes="saxon" xmlns:fos="java.io.FileOutputStream">
  
  <!-- Indent in the output -->
  <xsl:output indent="yes"/>
  
  <!-- Match the root -->
  <xsl:template match="ProcessImage">
    <Import> <!-- Insert our Import Node -->
      <Archive ConnectionID="1" Name="1"> <!-- Define our Application Connection String -->
        <Document pass="True"> <!-- Statically set documents to pass -->
          <xsl:for-each select="Pages/Page"> <!-- Ignore -->
            <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
          </xsl:for-each>
          <xsl:apply-templates select="DataArea/Image/Detail"/>
        </Document>
      </Archive>
    </Import>
  </xsl:template>
  
  <xsl:template match="Detail">
    <DocFile FileLoc="C:\SHARE FOLDER\SCANNED FILES\Scan{format-number(position() - 1, '0000')}.tif" /> <!-- Get the Filepath, give it a filename based on its position in the XML -->
    <Fields>
      <xsl:apply-templates select="parent::Image/Header/*[not(self::Count)]"/> <!-- Get Header Data, Ignore Count Node if Present, Apply Templates at bottom of XSL -->
      <xsl:apply-templates select="*[not(self::ImageData)]"/> <!-- Ignore Image Data Node if Present -->
    </Fields>
  </xsl:template>
  
  <xsl:template match="Header/* | Detail/*">  <!-- Match Header OR Detail Child Elements -->
    <Field Name="{name()}" value="{.}" pass="True"/>
  </xsl:template>
  <!-- Get Image Data
  <xsl:template match="ProcessImage">
   <xsl:variable name="img" select="ImageData"/>
   <xsl:variable name="fos" select="fos:new(string($img))"/>
   <xsl:value-of select="fos:write($fos,saxon:base64Binary-to-octets(xs:base64Binary(my-base64-encoded-image)))"/>
   <xsl:value-of select="fos:close($fos)"/>
</xsl:template>
  -->
</xsl:stylesheet>

Open in new window

sample.xml
0
Comment
Question by:lm1189
1 Comment
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 39277504
<!-- Begin XST Style Sheet -->
<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:saxon="http://saxon.sf.net/" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="saxon" 
  xmlns:fos="java.io.FileOutputStream">
  
  <!-- Indent in the output -->
  <xsl:output indent="yes"/>
  
  <!-- Match the root -->
  <xsl:template match="ProcessImage">
    <Import> <!-- Insert our Import Node -->
      <Archive ConnectionID="1" Name="1"> <!-- Define our Application Connection String -->
        <Document pass="True"> <!-- Statically set documents to pass -->
          <xsl:for-each select="Pages/Page"> <!-- Ignore -->
            <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
          </xsl:for-each>
          <xsl:apply-templates select="DataArea/Image/Detail"/>
        </Document>
      </Archive>
    </Import>
  </xsl:template>
  
  <xsl:template match="Detail">
    <DocFile FileLoc="C:\SHARE FOLDER\SCANNED FILES\Scan{format-number(position() - 1, '0000')}.tif" /> <!-- Get the Filepath, give it a filename based on its position in the XML -->
    <Fields>
      <xsl:apply-templates select="parent::Image/Header/*[not(self::Count)]"/> <!-- Get Header Data, Ignore Count Node if Present, Apply Templates at bottom of XSL -->
      <xsl:apply-templates select="*"/>
    </Fields>
  </xsl:template>
  
  <xsl:template match="Header/* | Detail/*[not(self::ImageData)]">  <!-- Match Header OR Detail Child Elements -->
    <Field Name="{name()}" value="{.}" pass="True"/>
  </xsl:template>

  <xsl:template match="Detail/ImageData">
   <xsl:variable name="img" select="concat('file:///c:/test', format-number(count(parent::Detail/preceding-sibling::Detail), '0000'), '.jpg')"/>
  <xsl:variable name="fos" select="fos:new(string($img))"/>
   <xsl:value-of select="
     fos:write($fos,
     saxon:base64Binary-to-octets(xs:base64Binary(.)))"/>
   <xsl:value-of select="fos:close($fos)"/>
</xsl:template>
 </xsl:stylesheet>

Open in new window


I changed your code a bit so at least the XSLT is correct and does what you expect.
But I can't get it to work since I somewhere have a second copy of FileOutputStream on my classpath and I can't get that message out
Note that your base64 snippets are not correct too
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question