cancel
Showing results for 
Search instead for 
Did you mean: 

Call an XSLT mapping from Java or Graphical Mapping

0 Kudos

Is there API or other tool to invoke an XSLT mapping from within a UDF(graphical mapping) function or a java mapping? I have a need to take a particular branch of an XML document, remove the namespaces, and then escape it, and fill it in a target node. The escaping is not a problem, but I need a way to remove namespaces from only a single branch of the XML tree.

So something like this:

<ns0:PurchaseOrderArchive>
  <ns0:Header>
    <ns0:Line>
...
    </ns0:Line>
  </ns0:Header>
<ns0:PurchaseOrderArchive>

Needs to become this:

<ns0:PurchaseOrderEscaped>
  &ltHeader>
    &ltLine>
    </Line>
  </Header>
<ns0:PurchaseOrderEscapted>
 

Passing the node a string to a UDF that invokes an xslt is the first approach I have tried. If I include an XSLT in a jar locally, I can invoke it using the following code:

public enum XSLTransformer implements XMLTransformer {
  REMOVE_NAMESPACES("xsl/RemoveNamespaces.xsl");
  Transformer transformer;
  private XSLTransformer(String xsltName) {

    URIResolver xsltLoader = new URIResolver() {
      @Override
      public Source resolve(String href, String base) 
             throws TransformerException {
        try {
          InputStream is = ClassLoader.getSystemResourceAsStream(href);;
          return new StreamSource(is, href);
        } catch (Exception ex) {
          throw new TransformerException(ex);
        }
      }
    };

    TransformerFactory tFactory = TransformerFactory.newInstance();
    tFactory.setURIResolver(xsltLoader);
    try {
      Source xsltSource = xsltLoader.resolve(xsltName, "");
      transformer = tFactory.newTransformer(xsltSource);
    } catch (TransformerConfigurationException e) {
      throw new AssertionError(e);
    } catch (TransformerException e) {
      throw new AssertionError(e);
    }
  }

  @Override
  public String tranform(String inString) throws XMLTransformException {
    StringWriter outputWriter = new StringWriter();
    Result outputTarget = new StreamResult(outputWriter);
    Source inSource = new StreamSource(new StringReader(inString));
    try {
      transformer.transform(inSource, outputTarget);
    } catch (TransformerException e) {
      throw new XMLTransformException(e);
    }
    return outputWriter.toString();
  }
}


Note the path to the XSLT in the jar is "xsl/RemoveNamespaces.xsl"

If I load this to PI as an imported archive, the resolution of the xsl no longer works and I get a FileNotFoundException. It would see that PI does some repackages of the jar contents.

Any thoughts about how something this this can be accomplished?

Accepted Solutions (0)

Answers (1)

Answers (1)

nabendu_sen
Active Contributor
0 Kudos

Hi Thomas,

Create a new XSD / Message Type from the xml with your desired Node: <ns0:PurchaseOrderEscaped> and add an additional graphical mapping step in your Operation Mapping which will pass values from Source <ns0:PurchaseOrderArchive> to Target <ns0:PurchaseOrderEscaped>. Rest of the nodes and fields in this new XSD / Message Type would be identical to the Original Target XSD/ Message Type.

Regards,

Nabendu.